Reputation: 1921
Someone has asked me, why this code produces a random number:
double a = 75.0;
printf("%d\n", a);
I thought the reason was that 4 bytes of the double
are interpreted as an integer, but the printed value was different each time the program was run. So i started to try some more things and found that this:
printf("%d\n", 75.0, 6);
actually prints out number 6. So i thought that the compiler is trying to fix the arguments so that they match the format string, but then i tried this:
const char *formats[] = { "%d %.1f\n", "%.1f %d\n" };
int whichFormat = 0;
scanf("%d", &whichFormat);
printf(formats[whichFormat&1], 2.5, 7, 1.2);
The formatting string now isn't even known at compile time, but it still somehow manages to match the argument types to the formatting string, printing either 7 2.5
or 2.5 7
depending on the input. The last value (1.2) was not printed.
All of this can be reproduced at compileonline.com which claims to be using GNU GCC 4.8.1.
What is going on here?
Upvotes: 2
Views: 239
Reputation: 399863
Undefined behavior is going on.
Such behavior is undefined, so it's very hard to reason about, and also somewhat pointless to do experiments, since there's no guarantee that the behavior stays the same (i.e. well-defined) for the same input. The behavior is, after all, undefined.
The first example, for instance, might read an expected integer argument from one register, while the actual floating-point argument is in another. I'm not saying this is what happens on any known machine, but it could be like that.
Upvotes: 5