为什么以及如何选择匹配的参数?

Det*_*roc 1 c

有人问我,为什么这段代码产生一个随机数:

double a = 75.0;
printf("%d\n", a);
Run Code Online (Sandbox Code Playgroud)

我认为原因是4个字节double被解释为整数,但每次运行程序时打印值都不同.所以我开始尝试更多的东西,发现这个:

printf("%d\n", 75.0, 6);
Run Code Online (Sandbox Code Playgroud)

实际上打印出6号.所以我认为编译器试图修复参数,使它们匹配格式字符串,但后来我尝试了这个:

const char *formats[] = { "%d %.1f\n", "%.1f %d\n" };
int whichFormat = 0;
scanf("%d", &whichFormat);
printf(formats[whichFormat&1], 2.5, 7, 1.2);
Run Code Online (Sandbox Code Playgroud)

格式化字符串现在甚至在编译时都不知道,但它仍然以某种方式设法将参数类型与格式化字符串匹配,打印7 2.52.5 7根据输入.最后一个值(1.2)未打印.

所有这些都可以在compileonline.com上复制,它声称使用的是GNU GCC 4.8.1.

这里发生了什么?

unw*_*ind 5

未定义的行为正在进行中.

这种行为是不确定的,因此很难推理,也有点无意义的做实验,因为不能保证行为对于相同的输入保持相同(即明确定义).毕竟,这种行为是未定义的.

例如,第一个示例可能从一个寄存器读取预期的整数参数,而实际的浮点参数在另一个寄存器中.我不是说这是任何已知机器上发生的事情,但它可能就是这样.

  • 最好只是纠正格式规范并继续前进,尽管了解流氓结果的来源可能具有教育意义. (2认同)