You wrote that "nothing happens", but the code actually works as expected (with some assumptions about the architecture, such as that ints and floats are both 32-bit). At least it prints something, but the result is probably not what you expected.
On Ideone.com the printed output is 0.000000
. The reason for this is that the integer value 37 interpreted as float value is 5.1848e-44. When using the "%f" format specifier in printf
, this extremely small number will be rounded to zero. If you change the format string to "%e", the output would be 5.184804e-44
. Or if you would change the value of i
to 1078530010, the output would be 3.141593
, for example.
(NB: Note that the value is actually first converted from float to double, and the double is passed to printf()
. The "%f" format specifier also expects a double, not a float, so that works out well.)
There's certainly truth in many of the already posted answers. The code indeed violates the strict aliasing rule, and in general, the results are defined. This is mostly because data types can differ between different CPU architectures (different sizes, different endianness, etc.). Also, the compiler is allowed to make certain assumptions and try to optimize your code, causing the compiled executable to behave different than intended.
In practice, the intended behavior can be "forced" by using constructs such as volatile pointers, restricting the compilers ability to optimize the code. Newer versions of the C/C++ standard have even more advanced constructs for this. However, generally speaking, for a given target architecture of which you know the data sizes and formats, the code you posted can work correctly.
However, there is a better solution, and I'm surprised nobody has mentioned it yet. The only (somewhat) portable way to do this without breaking the strict aliasing rule, is using unions. See the following example (and demo at ideone.com):
#include <stdio.h>
int main(void) {
union {
int i;
float f;
} test;
test.i = 1078530010;
printf("%f", test.f);
return 0;
}
This code also prints 3.141593
, as expected.