3 ms·
#include <stdio.h> int main() { float a = 12.5; printf("%d\n", a); printf("%d\n", *(int *)&a); return 0; } This program invokes
by FreeFull 11y ago
#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
This program invokes undefined behaviour when it casts float\* to int\*, so technically it could print anything, or do something else. I'm not sure how using memcpy instead would impact the puzzle's point though.
- JoeAltmaier 11y agoTechnically, it will print the first N bytes of the float as an int. Where N is the number of bytes ints compile to on the platform. So with knowledge of the platform, the result is entirely predictable.
- adsche 11y agoOnly with knowledge of platform AND compiler, though. Also these are C puzzles and casting pointers to incompatible types and dereferencing them is undefined behavior. Using memcpy would indeed fix this according to e.g. [1]. [1] http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-... (section "Violating Type Rules")
- unwind 11y agoActually it invokes undefined behavior when it passes a float to printf() and then tries to print it using %d (which of course expects int). Don't do that.
- deleted 11y ago[deleted]
- je-so 11y agoIf you know that sizeof(float) >= sizeof(int) the memory alignment should be fine. Also in this case * (int* )&a does not access any bytes outside of an defined data object. To predict the outcome one have to know the representation of float (IEEE 754) and the big/little endian issues which could be different between floats and ints. printf("%d\n", a) does promote the value a to a double first (promotion rules) and then either the first or last part i(assuming sizeof(double) == 2*sizeof(int)) is shown depending on little or big endian architecture.
- opcvx 11y agoYou don't know C. Reinterpreting an object as an incompatible object is undefined. int and float are incompatible. C Standard also specifically states that using an incorrect printf format specifier will result in undefined behavior.
- FreeFull 11y agoI have experimented with printf("%d\n", a); using gcc. When compiled for 32-bit x86, it displays the lower 32 bits of the double (which for 12.5 happen to be all 0). On x86-64, it displays a random value each time, which actually happens to be some pointer (randomised by ASLR). This is because register passing is used on x86-64, and the the double is stored into a floating point register, but %d reads from a different register. printf("%d\n", * (int*)&a); produces the number 1095237632 for both x86 and x86-64.
- userbinator 11y agoUB according to the standard has no restrictions, but I think the point of these puzzles is to explain what could reasonably happen on a typical system, and why.