Search

S.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. The latter four are sometimes referred to as named 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 convert i1 to a floating point value. Because i1 is a floating point value, i2 will then be converted 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:

Although a C-style cast appears to be a single cast, it can actually perform a variety of different conversions depending on context. This includes a const cast or reinterpret cast (both of which we mentioned above you should avoid). As a result, C-style casts are at risk for being inadvertently misused, and not producing the expected behavior, something which is easily avoidable by using the C++ casts instead.

If you’re curious, this article has more information on how C-style casts actually work.

Rule: Avoid using C-style casts

static_cast

C++ introduces a casting operator called static_cast. You’ve 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 takes a single value as input, and outputs the same value converted to the type specified inside the angled brackets. 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 (as the compiler can’t tell whether the integer will overflow the range of the char or not), and so the compiler will typically complain.

To get around this, we can use a static cast to explicitly convert our integer to a char:

When we do this, we’re explicitly telling the compiler that this conversion is intended, and we accept responsibility for the consequences (e.g. overflowing the range of a char if that happens). Since the output of this static_cast is a char, the assignment of said char to char variable ch doesn’t generate any type mismatches, and hence no warnings.

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:

Summary

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.

Quiz

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

Quiz Answers

1) Show Solution

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

96 comments to S.4.4a — Explicit type conversion (casting)

  • Radioga

    I have a doubt about this sentence: "Because C-style casts are not checked by the compiler at compile time, C-style casts can be inherently misused". In my experience the C-style cast is checked by the compiler; for example this little program cannot compile:

    the output console of Visual Studio 2017 says me:

    error C2440: 'type cast': cannot convert from 'float' to 'char **'

    • Alex

      I've updated the article a bit with better reasons not to use C-style casts, and added a link with more detail on how C-style casts work for the curious. Thanks!

  • daniel jo

    "Static_cast takes as input a values" this bit confuses me.. can u explain what u mean

  • Q

    Can you give more examples of why c++ style cast should be preferred? C style casts have always worked fine for c and java for that matter. I don't understand why they took something simple from C and replaced it with this over complicated ugly, and cumbersome mess. What ever happened to if it ain't broke don't fix it?

    • Alex

      C++ style casts should be preferred because:
      1) They allow you to better express your intent.
      2) C-style casts might do any number of things (and sometimes different things depending on context), and it's not always clear which one is being invoked from reading the code.
      3) They're easier to find in your code precisely because they're "ugly" and differentiated.
      4) At least in the case of dynamic_cast<>, they can do things that C-style casts can't.

      There's nothing that says you have to give up C-style casts if you want to, but C++ styles casts are safer. https://anteru.net/blog/2007/c-background-static-reinterpret-and-c-style-casts/ has a little bit of additional information as well as an example of where C-style casts can go wrong.

  • James

    ```
    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
    ```
    I believe that's not actually what happened there. "static_cast" is an unary operator with high precedence level(2) which takes in one expression of a type and return that expression with the type programmer desired. So, compiler giving a warning for doing unsafe conversion on type-converting operator which purpose is to convert type makes no sense, so it won't. And when we do "i = static_cast<int>(i / 2.5);", "static_cast<int>(i/2.5);" will be evaluated first since "static_cast" operator has higher precedence lever than "operator=". When compiler evaluate "operator=", it see an int being assigned to an int so no warning.
    I've confirmed it by using -Wconversion I found in a comment by @nascardriver. Try something like "float x= 3; int y = static_cast<double>(x);" and see your compiler still give warning even when you're using "static_cast".

    • Alex

      I take your point -- the original wording left something to be desired. I've updated the lesson text to be more explanatory around what's happening without losing the "programmer is taking responsibility" angle.

  • Anonymous

    Why should casting be avoided? Wouldn't it be better to use (static) casting always instead of letting it happen implicitly?

  • jih332

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

    however I didn't find any issue by doing this on my side, I'm using

    to compile my code. what could be the reason for this? Thanks in advance.

  • NAMIT KHANDUJA

    what is type cast operator?

    #include <iostream>
    using namespace std;

    class A {};

    class B {
    public:
      // conversion from A (constructor):
      B (const A& x) {}
      // conversion from A (assignment):
      B& operator= (const A& x) {return *this;}
      // conversion to A (type-cast operator)
      operator A() {return A();}
    };

    int main ()
    {
      A foo;
      B bar = foo;    // calls constructor
      bar = foo;      // calls assignment
      foo = bar;      // calls type-cast operator
      return 0;
    }

  • Benur21

    Can we use

    in C++?

    Also, what do you mean by getting rid of a const?

Leave a Comment

Put all code inside code tags: [code]your code here[/code]