Copying bit pattern of a float
value into a uint32_t
or vice versa (not casting them), we can copy bits byte-to-byte using std::copy
or memcpy
. Another way is to use reinterpret_cast
as below (?):
float f = 0.5f;
uint32_t i = *reinterpret_cast<uint32_t*>(&f);
or
uint32_t i;
reinterpret_cast<float&>(i) = 10;
However there is a claim that says two reinterpret_cast
used above, invokes undefined behavior. Is that true? How?
Yes, this is undefined behaviour as it breaks the strict aliasing rule:
[basic.lval]/10:
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined — the dynamic type of the object,— a cv-qualified version of the dynamic type of the object,
— a type similar (as defined in 4.4) to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
— an aggregate or union type that includes one of the aforementioned types among its elements or non- static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
— a type that is a (possibly cv-qualifded) base class type of the dynamic type of the object,
— a char or unsigned char type.
Since uint32_t
is none of the above when trying to access an object of type float
, the behaviour is undefined.