Reputation: 425
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?
Upvotes: 4
Views: 151
Reputation: 400224
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.
Upvotes: 8
Reputation: 1
You are probably hitting some undefined behavior; printing a float as a pointer has absolutely no sense.
And GCC 4.8 invoked as gcc -Wall
rightly warns you:
dwakar.c:5:3: warning: format '%p' expects argument of type 'void *',
but argument 3 has type 'double' [-Wformat=]
printf("%f %p",i,i);
^
So please use gcc -Wall
to compile your code and correct it till no warnings are given.
Notice that at the ABI level floating point and pointers arguments are passed thru different registers. So the implementation probably prints as pointer the (uninitialized, or old) content of whatever register is involved.
Upvotes: 3
Reputation: 121387
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]
Upvotes: 8