4.4a — Explicit type conversion (casting)

In the previous section 4.4 -- Implicit type conversion (coercion), you learned that the compiler will sometimes implicitly convert a value from one data type to another. When you want to promote a value from one data type to a larger similar data type, using the implicit type conversion system is fine.

Many new programmers try something like this: float f = 10 / 4;. However, because 10 and 4 are both integers, no promotion takes place. Integer division is performed on 10 / 4, resulting in the value of 2, which is then implicitly converted to 2.0 and assigned to f!

In the case where you are using literal values (such as 10, or 4), replacing one or both of the integer literal value with a floating point literal value (10.0 or 4.0) will cause both operands to be converted to floating point values, and the division will be done using floating point math.

But what if you are using variables? Consider this case:

Variable f will end up with the value of 2. How do we tell the compiler that we want to use floating point division instead of integer division? The answer is by using a type casting operator (more commonly called a cast) to tell the compiler to do explicit type conversion. A cast represents an explicit request by the programmer to do a type conversion.

Type casting

In C++, there are 5 different types of casts: C-style casts, static casts, const casts, dynamic casts, and reinterpret casts.

We’ll cover C-style casts and static casts in this lesson. Dynamic casts we’ll save until after we cover pointers and inheritance.

Const casts and reinterpret casts should generally be avoided because they are only useful in rare cases and can be harmful if used incorrectly.

Rule: Avoid const casts and reinterpret casts unless you have a very good reason to use them.

C-style casts

In standard C programming, casts are done via the () operator, with the name of the type to cast to inside. For example:

In the above program, we use a float cast to tell the compiler to promote i1 to a floating point value. Because i1 is a floating point value, i2 will then be promoted to a floating point value as well, and the division will be done using floating point division instead of integer division!

C++ will also let you use a C-style cast with a more function-call like syntax:

Because C-style casts are not checked by the compiler at compile time, C-style casts can be inherently misused, because they will let you do things that may not make sense, such as getting rid of a const or changing a data type without changing the underlying representation (leading to garbage results).

Consequently, C-style casts should generally be avoided.

Rule: Avoid C-style casts


C++ introduces a casting operator called static_cast. You’re previously seen static_cast used to convert a char into an int so that std::cout prints it as an integer instead of a char:

Static_cast is best used to convert one fundamental type into another.

The main advantage of static_cast is that it provides compile-time type checking, making it harder to make an inadvertent error. Static_cast is also (intentionally) less powerful than C-style casts, so you can’t inadvertently remove const or do other things you may not have intended to do.

Using casts to make implicit type conversions clear

Compilers will often complain when an unsafe implicit type conversion is performed. For example, consider the following program:

Casting an int (4 bytes) to a char (1 byte) is potentially unsafe, and the compiler will typically complain. In order to announce to the compiler that you are explicitly doing something you recognize is potentially unsafe (but want to do anyway), you can use a cast:

In the following program, the compiler will typically complain that converting a double to an int may result in loss of data:

To tell the compiler that we explicitly mean to do this:


Casting should be avoided if at all possible, because any time a cast is used, there is potential for trouble. But there are many times when it can not be avoided. In most of these cases, the C++ static_cast should be used instead of the C-style cast.


1) What’s the difference between implicit and explicit type conversion?

Quiz Answers

1) Show Solution

4.4b -- An introduction to std::string
4.4 -- Implicit type conversion (coercion)

32 comments to 4.4a — Explicit type conversion (casting)

  • Abhishek

    This paragraph(and anything after it)went over my head::

    “The C style cast can be inherently misused, because it will let you do things that may not make sense, such as getting rid of a const or changing a data type without changing the underlying representation. C introduces a new casting operator called static_cast. A static cast works similarly to the C style cast, except it will only do standard type conversions, which reduces the potential for inadvertant misuse”
    I didn’t get the difference b/w Cpp style cast,C style cast and static_cast…………I think all of them do the same thing…only the syntax is different.????

    • The purpose of static_cast is to do normal conversion between types without runtime checks. C++ provides several other types of casts, including dynamic_cast, reinterpret_cast, and const_cast, all of which have different behavior.

      The problem with C-style casting is that it may use a static_cast, reinterpret_cast, or const_cast (or a combination thereof) depending on the situation, and we’re not always sure which one(s) it’s going to pick. That’s why using static_cast is safer -- we’re always sure what it’s going to do, and if we try to do something it wasn’t meant for, it will give us a warning.

      Here’s an example of a C-style cast:

      Not only is this casting a char to an unsigned char, it’s also tossing away the const. I think it’s doing a reinterpret_cast and a const_cast combination. In any case, you can see that this is dangerous. Let’s try using a C++ style static_cast instead:

      When we try to compile this, the compiler will complain:

      In other words, the C++ style casts give you more control over what type of casting you want to perform, and will warn you if you do something that violates the constraints on the cast. On the other hand, C-style casts will try to convert whatever you throw at it, regardless of whether it really makes sense to be doing so. This is dangerous and can lead to unexpected behavior.

  • Alok

    Even after using static_cast, i am getting compiler warning “warning (etoa:1643): narrowing or signed-to-unsigned type conversion found: unsigned long to unsigned short”.

    I am trying to assigned int variable to short int variable.

  • spacedmonkey


    I just have a query about casting. When you cast a variable from one type to another in order to carry out some statement or other, is the variable permanently changed to this type or is it just temporarily changed at the point where the cast command is used?

    For instance:

    nValue1 is cast as a float in line 3 (and nValue2 is changed to a float as well I assume). Is nValue1 (and nValue2) a float from this point on in the program or does it retain its original type of int?

    • Anu

      Hi spacedmonkey,

      I tried to answer your question…by running the following code:

      The output is 2.5, 10 and 4
      So, this means that the values of nValue1 and nValue2 are temporarily casted as floats, just for evaluating that expression.

    • They are temporarily cast. If you don’t assign those temporary values to anything, they are lost. The original variable is not changed.

  • Chip Blach

    Casting is at the discression of the programmer. I have had cases where I have had to cast an integer
    as a array of 4 unsigned chars.
    If the program needs it, cast it, if it does not, dont do it.

    In c++ it is always better not to cast, but to stick with strict assignments which are provided.


  • joel.giedt

    One common type casting that comes up all the time in codes I work with is switching between different types of pointers. The most unavoidable example is something like

    Float *ptr = (Float *)smalloc(num_bytes);

    Because smalloc() is like malloc in that it returns a void type. You might wonder why not use the new operator for dynamic allocation? The reason is that on the architecture we are using (e.g., BlueGene L/P/Q) we want to align the memory usage properly in order to avoid cache misses. So we write a function smalloc() that takes care of all that for us, which new would not do if we are using the GNU compiler (maybe IBM’s compiler will do it automatically, I don’t know). We can also write into it code to verify the allocation was successful and if not, report the class and function where the error occured,

    Float *ptr=(Float *)smalloc(num_bytes,cname,fname);

    Also Float is some typedef, probably float or double, depending on the precision we’ve decided to use.

    Another use, which looks dangerous, but we do it anyways because we care more about performance than C++ doctrine, is something like:

    int num_bytes = N*2*sizeof(Float);
    Complex *c=(Complex *c)smalloc(num_bytes);
    // next, code that fills in the array of complex numbers …
    Float *temp=(Float *)c;
    // Now we want the norm of the complex vector, and we use an optimized function that say uses standard reduction algorithm to take advantage of multithreading on our 64-way processor, or maybe on a GPU accelerator:
    Float my_norm=norm(temp,N*2);

    By converting to Float array, the complex array looks just like an array of floats 2*N long and norm knows what to do with such an array. If norm is a library function that we a calling from some external package, it probably has no idea what to do with our abstract Complex type. So we trick it. Is it “dangerous”? Maybe, but so is driving a car.

    Another trick may be if we have to call MPI_Send() and MPI_Recv() to send the array of Complex numbers between compute nodes. Then Float* typically means something to these functions, but Complex* does not. It would be ridiculous to copy the array elements into a float array just to communicate them when a simple type casting does the job (provided we do not use the C++ standard complex class, but rather our own class with just two data elements -- note that they also cannot be private, again for performance reasons -- we’d be friending practically every function in our code, which is plain silly).

  • Peter

    In the C-style casts example you have variable i1 but then you talk about nValue1

  • Todd


    "A cast represents a (an) explicit request"

    "making it less easy to make an inadvertent error" (I would say "making it harder…", but now I’m being picky)

  • Shivam Tripathi

    hii alex…once again need ur help..:)..consider this code snippet..

    [ int a=15;
      float c= static_cast <float> (a);
      std::cout<< a<<"t"<< &a <<std::endl;
      std::cout<< c <<"t"<< &c <<std::endl;
      return 0;
    o/p:- 15  0x23fe4c
          15  0x23fe48..

    my query is that suppose we need to use only float value further in our code…so the memory being allocated to the ‘int’ one will be useless…can we free that??…why do such wastage of the memory…plzz help..

    • Alex

      Local variables exist until they go out of scope at the end of the block they are defined in. There’s no way to manually deallocate them before that point.

      Honestly though, it doesn’t matter. The memory use of an extra variable (or even tens of extra variables) is insignificant.

  • Shivam Tripathi

    hmm…got it…thanku so much Alex…:)

  • Rahul Agrawal

    this also are part of explicit type casting. Can you please add some information about this.Specially dynamic_cast. where to use static_cast and where to use dynamic_cast creates lots of confusion.

  • Gergő

    Hi Alex!

    "Because C-style casts are not checked by the compiler at compile type"

    Isn’t "type" supposed to be "time" there?

    I’m working on a full Hungarian translation for the entire collection of chapters here and this gave me some minutes of head scratching.
    By the way, i’m just doing it to burn the info in deeper than by simply reading, but if you may be interested in turning this site to multilingual, you can send me a template showing exactly how you’d expect the translated material sent to you so you don’t need to do any work with it other than opening up a folder to copy into. And when i’m done i’d send you the entire stuff in Hungarian. A couple thousand Hungarian clicks over time couldn’t hurt you i guess…

    • Alex

      Thanks for catching that typo.

      The site currently doesn’t have infrastructural support for multiple languages. I also actively update the articles for clarity and typo-fixing -- I’m not sure how I’d be able to keep translations up to date.

  • Rajender

    If we assign a static type cast of different data type of a variable to itself, wouldn’t it should give an error or not kindly look into this code

    • Alex

      No, there’s no error here.

      Let’s take this in two steps.

      First static_cast(k) happens, and k is explicitly converted into an int, with value 2.

      Second, k is assigned integer value 2. This results in an implicit conversion from int (2) to float (2.0), which is then assigned to float k.

      As a side note, the first line should be:

      Floating point literals default to type double without an f suffix.

      • Shiva

        A question on that side note:

        Floating point literals default to type double, but then, won’t it be implicitly type converted into float so that the float variable ‘k’ can be initiated with it? Is it to avoid this conversion altogether that we add the ‘f’ suffix? Since ‘k’ is defined float, it won’t be converted into double somehow. Or am I missing something?

        • Alex

          Yes, we add the f to avoid the conversion. If we tried to assign a double literal to a float variable, C++ would try to convert it, which could cause truncation or rounding errors to happen.

  • yash

    what is dynamic_cast and reinterpret_cast?

    • Alex

      dynamic_cast is used to convert pointers and references between base class and derived class objects. For example, if you have a base class A, and a derived class B, and a base class pointer A* that points to an object of type B, you’d use a dynamic_cast to convert the pointer from A* to B*. If this sounds like gibberish, it’ll make more sense once you’ve learned about pointers and inheritance.

      reinterpret_cast is used when you want to change the type of an object but leave the underlying bits alone (static_cast will cause the underlying bits to be converted to the new type). There are very few situations in which this is necessary/desirable, and most of them are hacky.

  • Sushant

    Hi Alex,
    Are you planning to add other cpp casting too. It would be great if you could cover RTTL too.

    Thanks for creating such a great cpp learning resource with clear and concise examples.


    • Alex

      RTTL is just dynamic casts and typeid -- I already covered typeid informally in chapter 2, and dynamic casts are covered later when we get into inheritance.

  • Byron

    Hello there,

    Can you please explain how, in the last example (i = 1/2.5) data will be lost?
    i = 100, so 100 / 2.5 would be 40, which is an integer.
    Do you mean that the compiler will recognise that dividing with 2.5 (float/double) may lead to a result with non-zero decimals and that, when converted back to int (since i is int), the decimals will be lost?

    • Alex

      Yes, that’s exactly what it means. In this case, since 2.5 can be represented precisely, and 100 / 2.5 leads to an integer, there’s no precision lost. But in many cases, the result of a division containing a float won’t be an integer -- so most compilers will complain in general about any implicit conversion from a floating point type to an integer type. Even in the cases where the result should be an integer, precision issues may lead to the wrong result. Hypothetically, if 2.5 ended up getting represented as 2.5000001, then 100/2.5000001 could end up as 39.9999998, which would get truncated to integer 39.

  • reznov

    In physics we often use ‘variable’ constants like gravity. Is it possible to write a program that can overwrite a constant like gravity using C-conversion and lock it back in again?

    i.e. I ask the user to specify his/her country, a case diagram will link the specific gravity to that country and overwrite the current ‘const g_gravity’ and locks it back in so nothing else can touch it.

    That would be lovely for us physicists 🙂

    • Alex

      Nope. Generally it’s a bad idea to cast away const unless you know the object was created non-const -- the compiler will make a lot of optimizations for const objects, and if you try to make them non-const, undefined behavior will result. So if you want something that changes values (even once), you’ll have to make it non-const.

      But that’s not such a bad thing. You can encapsulate your gravity variable so it can’t be touched directly (either by making it static in a file and providing functions to modify/set it, or putting it in a class as a private member and adding member functions to modify/set it).

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter