Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

printf for float behaves differently if position changed

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?

like image 948
Diwakar Sharma Avatar asked Dec 01 '22 21:12

Diwakar Sharma


2 Answers

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.

like image 124
Adam Rosenfield Avatar answered Jan 08 '23 20:01

Adam Rosenfield


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]

like image 28
P.P Avatar answered Jan 08 '23 20:01

P.P