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_c
If you are trying to convert the bits of your int
to a the representation of a double
, you need to cast the address not the value. You must also make sure the sizes match:
uint64_t x = 0x4045000000000000;
double y = *reinterpret_cast<double *>(&x);
reinterpret_cast is not a general cast. According to the C++03 spec 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.
And there is nothing listed that describes converting between integral and floating point types (or between integral types, even this is illegal reinterpret_cast<long>(int(3));
)
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.
Use a union. It is the least error-prone way to memory map between an integer and a floating point type. Reinterpreting a pointer will cause aliasing warnings.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
union { uint32_t i; float f; } v; // avoid aliasing rules trouble
v.i = 42;
printf("int 42 is float %f\n", v.f);
v.f = 42.0;
printf("float 42 is int 0x%08x\n", v.i);
}