I understand that reinterpret_cast
is dangerous, I'm just doing this to test it. I have the following code:
int x = 0; double y = reinterpret_cast<double>(x);
When I try to compile the program, it gives me an error saying
invalid cast from type 'float' to type 'double
What's going on? I thought reinterpret_cast
was the rogue cast that you could use to convert apples to submarines, why won't this simple cast compile?
There are very few valid uses of reinterpret_cast , most of them result in UB. Plus it is practically impossible to check if the use is valid. So reinterpret_cast is not allowed during compilation, i.e. it is not allowed in constexpr.
The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.
reinterpret_cast is a very special and dangerous type of casting operator. And is suggested to use it using proper data type i.e., (pointer data type should be same as original data type).
The dynamic cast is the only that needs to be "calculated" in run-time. All other casts are calculated in compile-time. The machine code for a static_cast is a fixed function based on the type you are casting FROM and TO. For reinterpret_cast , the machine code can be resolved in compile-time as well.
Perhaps a better way of thinking of reinterpret_cast
is the rouge operator that can "convert" pointers to apples as pointers to submarines.
By assigning y to the value returned by the cast you're not really casting the value x
, you're converting it. That is, y
doesn't point to x
and pretend that it points to a float. Conversion constructs a new value of type float
and assigns it the value from x
. There are several ways to do this conversion in C++, among them:
int main() { int x = 42; float f = static_cast<float>(x); float f2 = (float)x; float f3 = float(x); float f4 = x; return 0; }
The only real difference being the last one (an implicit conversion) will generate a compiler diagnostic on higher warning levels. But they all do functionally the same thing -- and in many case actually the same thing, as in the same machine code.
Now if you really do want to pretend that x
is a float, then you really do want to cast x
, by doing this:
#include <iostream> using namespace std; int main() { int x = 42; float* pf = reinterpret_cast<float*>(&x); (*pf)++; cout << *pf; return 0; }
You can see how dangerous this is. In fact, the output when I run this on my machine is 1
, which is decidedly not 42+1.
In C++ reinterpret_cast
can only perform a specific set of conversions, explicitly listed in the language specification. In short, reinterpret_cast
can only perform pointer-to-pointer conversions and reference-to-reference conversions (plus pointer-to-integer and integer-to-pointer conversions). This is consistent with the intent expressed in the very name of the cast: it is intended to be used for pointer/reference reinterpretation.
What you are trying to do is not reinterpretation. If you want to reinterpret an int
as a double
you'd have to convert it to a reference type
double y = reinterpret_cast<double&>(x);
although the equivalent pointer-based reinterpretation is probably more explicit
double y = *reinterpret_cast<double*>(&x); // same as above
Note though, that while reinterpret_cast
can convert the reference/pointer types, the actual attempt to read the data through the resultant reference/pointer produces undefined behavior.
And in any case this, of course, can't make much sense on a platform with int
and double
of different size (since in case of larger double
you will read beyond the memory occupied by x
).
So, in the end it all boils down to what you were trying to achieve. Memory reinterpretation? See above. Some kind of more meaningful int
to double
conversion? If so, reinterpret_cast
won't help you here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With