Does printf () depend on format specifiers?

#include<stdio.h> main() { float x=2; float y=4; printf("\n%d\n%f",x/y,x/y); printf("\n%f\n%d",x/y,x/y); } 

Conclusion:

 0 0.000000 0.500000 0 

compiled with gcc 4.4.3 The program exited with error code 12

+4
source share
6 answers

As noted in other answers, this is due to a mismatch between the format string and the type of the argument.

I assume that you are using x86 here (based on observed results).

Arguments are passed on the stack, and x/y , although of type float , will be passed as a double to the varargs function (due to rules of the type "advance").

An int is a 32-bit value, and double is a 64-bit value.

In both cases, you go twice x/y (= 0.5). The representation of this value as a 64-bit double is 0x3fe0000000000000 . As a pair of 32-bit words, it is stored as 0x00000000 (the least significant 32 bits), followed by 0x3fe00000 (the most significant 32-bit). Thus, the arguments on the stack, as seen from printf() , look like this:

 0x3fe00000 0x00000000 0x3fe00000 0x00000000 <-- stack pointer 

In the first of two cases, %d calls the first 32-bit value 0x00000000 , which must be popped up and printed. %f displays the following two 32-bit values, 0x3fe00000 (least significant 32 bits 64 double bits), and then 0x00000000 (most significant). The resulting 64-bit value 0x000000003fe00000 , interpreted as double , is a very small number. (If you change %f in the format string to %g , you will see that it is almost 0, but not quite).

In the second case, %f correctly displays the first double , and %d gives 0x00000000 half the second double , so it seems to work.

+15
source

When you say %d in the printf format string, you must pass the int value as the corresponding argument. Otherwise, the behavior is undefined, which means that your computer may crash, or aliens may knock on your door. Similarly for %f and double .

+7
source

Yes. The arguments are read from the vararg list in printf in the same order in which format specifiers are read.

Both printf statements are not valid because you use a format specifier that expects an int, but you only provide it with a float .

+4
source

What you do is undefiend behavior. What you see is random; printf could write something.

You must match the exact type when providing printf arguments. You can, for example, Cast:

 printf("\n%d\n%f", (int)(x/y), x/y); printf("\n%f\n%d", x/y, (int)(x/y)); 
+3
source

This result is not surprising, in the first% d you passed double, where an integer was expected.

+2
source

http://en.wikipedia.org/wiki/Format_string_attack

Something related to my question. Supports Matthew's answer.

0
source

All Articles