请解释以下代码的输出:
#include<stdio.h>
#include<stdlib.h>
#define SQUARE(x) (x*x*x)
int main() {
int x = 3;
int y = SQUARE(++x)/x++; // Undefined behavior even though it doesn't look
// like it here
printf("%d %d",x,y);
return 0;
}
输出:7 25
请解释y的值是如何变为25?
答案 0 :(得分:0)
这个宏被误称,但那只是一个红色的鲱鱼。这两个陈述扩展为:
int x = 3;
int y = (++x * ++x * ++x) / x++;
这是未定义的行为,因为x在序列点之间被多次修改。允许编译器做几乎任何事情;它可以交换x
的使用以及x
的前后增量几乎无论如何。它可以从左到右做事,在这种情况下,你得到:
int y = (4 * 5 * 6) / 6;
根据此计划,x
现在为7,y
现为20。
它可以从右到左做事:
int y = (7 * 6 * 5) / 3;
现在,y
是70。
它几乎可以在任何时候缓存x
的值并使用它。尝试在各种编译器下运行您的程序,具有各种优化级别。 gcc -O4
与cc
有何不同?实际上,引用了Internet术语文件:
鼻子恶魔:n。
在Usenet组comp.std.c上识别C编译器遇到未定义构造时的任何意外行为的简写。在1992年初对该组进行讨论时,常规评论“当编译器遇到[给定的未定义构造]时,让恶魔飞出你的鼻子是合法的”(这意味着编译器可能会选择任意奇怪的在不违反ANSI C标准的情况下解释代码的方法)。其他人后来提到了“鼻子恶魔”,很快就成立了。原始帖子可通过http://groups.google.com/groups?hl=en&selm=10195%40ksr.com进行网络访问。
所以,我在这里要小心得多。你想让恶魔飞出你的鼻子吗?