What explains the output of this C code?
#include <stdio.h>
struct abc{
int a;
int b;
} xyz;
int main()
{
xyz.a = 10;
xyz.b = 20;
printf("%d %d", xyz, xyz.a);
}
The output of of the above program is 10 20
.
If I add anot开发者_如何学JAVAher printf
statement as
printf("%d %d %d", xyz, xyz.a, xyz.b);
the output comes 10 20 10
.
What's the explanation for this?
It's because the call to printf
is pushing the entire structure xyz
onto the stack and that structure (in this case) consists of the two integers. The xyz.a
in that case is ignored since it's beyond the stack area that printf
cares about.
Although the behaviour is undefined(a) so that anything can happen, this particular case can be explained because the printf("%d %d",xyz,xyz.a);
statement probably pushes xyz
and xyz.a
on to the stack something like:
xyz.a | 10 | |
xyz | 20 | | Stack grows downward.
| 10 | V
and the printf
code itself, because it's been given two %d
's, will print the 10 at the bottom and the 20. In other words, it's a mismatch between the format string and the parameters.
When you add another %d
, it prints what it thinks is the third argument (but is actually the second), the top 10 in the above diagram.
I should mention that relying on this behaviour is not a good idea. It may change when you switch compilers, versions of the compiler, or possibly even on odd-numbered days :-)
Good compilers like gcc
actually look inside the printf
arguments to catch this as a potential error:
pax$ cat qq.c
#include<stdio.h>
struct abc { int a; int b; } xyz;
int main (void) {
xyz.a=10;
xyz.b=20;
printf("%d %d",xyz,xyz.a);
return 0;
}
pax$ gcc -Wall -o qq qq.c
qq.c: In function 'main':
qq.c:6: warning: format '%d' expects type 'int',
but argument 2 has type 'struct abc'
qq.c:6: warning: format '%d' expects type 'int',
but argument 2 has type 'struct abc'
(a) From c99, section 7.19.6.1/9
: If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
You've invoked undefined behavior; any result is allowed.
7.19.6.1 The fprintf function
...
9 If a conversion specification is invalid, the behavior is undefined.248) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Emphasis mine. xyz
is of type struct abc
, but printf
is expecting that argument to be type int
.
paxdiablo's answer is a decent postmortem of how such a result may occur, but that's only applicable to your specific circumstances. Change anything about the code or the translation environment or the execution environment, and the result will probably be different.
精彩评论