I've below piece of code :
float i=85.00;
printf("%f %p",i,i);
which prints o/p:
85.00000 (nil)
But when I change the order like below:
float i=85.00;
printf("%p %f",i,i);
the o/p is :
(nil) 0.00000
While I expect that similar o/p should be printed as earlier, in mentioned order. What is the behaviour going on can anyone please explain?
What you're doing is undefined behavior. The %p
format specifier promises that you're passing in a pointer (specifically a void*
pointer), and you're passing in a double
instead (float
values get promoted to double
when passed to variadic functions such as printf
). So as soon as you fail to satisfy the requirements, the compiler and implementation are free to do whatever they want, and printing out 0 instead of 85 in the second case is perfectly legal.
What's likely happening is that the compiler is using a calling convention which places floating-point values in separate registers (e.g. the x87 floating-point stack, or the SSE2 SIMD registers) instead of on the stack, whereas integer values like pointers get passed on the stack. So when the implementation sees a %p
format specifier, it tries to read the argument off of the stack, when in fact the argument is actually elsewhere.
As others have mentioned, you should really be compiling with the -Wall
option (assuming GCC or a GCC-compatible compiler). It will help you catch these kinds of errors.
printf()
expects a pointer for the format specifier %p
whereas you are passing the value of a float. This is undefined behaviour.
If you want to print the address, then pass the address:
printf("%f %p",i, &i);
If you turn on the warnings, you'll see the problem:
warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘double’ [-Wformat]
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