45

In traditional C you can do:

int i = 48;
char c = (char)i;
//Now c holds the value of 48. 
//(Of course if i > 255 then c will not hold the same value as i).  

Which of the c++ casting methods (static_cast, reinterpret_cast) is suited for getting this job done?

Subway
  • 5,286
  • 11
  • 48
  • 59
  • You can also do `char c = i;` and not worry about which cast is which. Of course, if you do that you'll run afoul of the "cast everywhere" folks who insist that compiler warnings be turned into errors and then fixed wherever they occur. – Pete Becker Jun 03 '13 at 17:25

4 Answers4

39

You can implicitly convert between numerical types, even when that loses precision:

char c = i;

However, you might like to enable compiler warnings to avoid potentially lossy conversions like this. If you do, then use static_cast for the conversion.

Of the other casts:

  • dynamic_cast only works for pointers or references to polymorphic class types;
  • const_cast can't change types, only const or volatile qualifiers;
  • reinterpret_cast is for special circumstances, converting between pointers or references and completely unrelated types. Specifically, it won't do numeric conversions.
  • C-style and function-style casts do whatever combination of static_cast, const_cast and reinterpret_cast is needed to get the job done.
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
36

You should use static_cast<char>(i) to cast the integer i to char.

reinterpret_cast should almost never be used, unless you want to cast one type into a fundamentally different type.

Also reinterpret_cast is machine dependent so safely using it requires complete understanding of the types as well as how the compiler implements the cast.

For more information about C++ casting see:

Community
  • 1
  • 1
Felix Glas
  • 15,065
  • 7
  • 53
  • 82
  • Assuming, of course, there's a good reason not to just write `char c = '0'` ... – Useless Jun 03 '13 at 14:28
  • @Useless The meaning of that is completely different from casting it from an int, you set it the the character '0' which is not the same as the number 0. – Kevin Jun 03 '13 at 14:32
  • 3
    But the same as the integer literal `48` in the question, assuming ASCII encoding. I'm allergic to hard-coding ASCII integer values, when character literals are anyway more readable. – Useless Jun 03 '13 at 14:34
  • Also, `reinterpret_cast` can't convert between integer types at all; so whether you "should" use it is irrelevant. – Mike Seymour Jun 03 '13 at 14:46
  • @Useless, this was just an example, in my case I don't have this number hard-coded, I have an enum which I need to insert into a char and I know I won't reach to beyond 255. Thanks though. – Subway Jun 03 '13 at 16:36
0

reinterpret_cast cannot be used for this conversion, the code will not compile. According to C++03 standard section 5.2.10-1:

Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.

This conversion is not listed in that section. Even this is invalid:

long l = reinterpret_cast<long>(i)

static_cast is the one which has to be used here. See this and this SO questions.

Community
  • 1
  • 1
Sanish
  • 1,699
  • 1
  • 12
  • 21
-1

Using static cast would probably result in something like this:

// This does not prevent a possible type overflow
const char char_max = -1;

int i = 48;
char c = (i & char_max);

To prevent possible type overflow you could do this:

const char char_max = (char)(((unsigned char) char(-1)) / 2);

int i = 128;
char c = (i & char_max); // Would always result in positive signed values.

Where reinterpret_cast would probably just directly convert to char, without any cast safety. -> Never use reinterpret_cast if you can also use static_cast. If you're casting between classes, static_cast will also ensure, that the two types are matching (the object is a derivate of the cast type).

If your object a polymorphic type and you don't know which one it is, you should use dynamic_cast which will perform a type check at runtime and return nullptr if the types do not match.

IF you need const_cast you most likely did something wrong and should think about possible alternatives to fix const correctness in your code.

guest
  • 19
  • 1