The short answer:
If you don't know what reinterpret_cast
stands for, don't use it. If you will need it in the future, you will know.
Full answer:
Let's consider basic number types.
When you convert for example int(12)
to unsigned float (12.0f)
your processor needs to invoke some calculations as both numbers has different bit representation. This is what static_cast
stands for.
On the other hand, when you call reinterpret_cast
the CPU does not invoke any calculations. It just treats a set of bits in the memory like if it had another type. So when you convert int*
to float*
with this keyword, the new value (after pointer dereferecing) has nothing to do with the old value in mathematical meaning.
Example: It is true that reinterpret_cast
is not portable because of one reason - byte order (endianness). But this is often surprisingly the best reason to use it. Let's imagine the example: you have to read binary 32bit number from file, and you know it is big endian. Your code has to be generic and works properly on big endian (e.g. some ARM) and little endian (e.g. x86) systems. So you have to check the byte order. It is well-known on compile time so you can write You can write a function to achieve this:constexpr
function:
/*constexpr*/ bool is_little_endian() {
std::uint16_t x=0x0001;
auto p = reinterpret_cast<std::uint8_t*>(&x);
return *p != 0;
}
Explanation: the binary representation of x
in memory could be 0000'0000'0000'0001
(big) or 0000'0001'0000'0000
(little endian). After reinterpret-casting the byte under p
pointer could be respectively 0000'0000
or 0000'0001
. If you use static-casting, it will always be 0000'0001
, no matter what endianness is being used.
EDIT:
In the first version I made example function is_little_endian
to be constexpr
. It compiles fine on the newest gcc (8.3.0) but the standard says it is illegal. The clang compiler refuses to compile it (which is correct).