你能解释下面的输出吗?

时间:2013-08-04 14:42:05

标签: c preprocessor-directive

请解释以下代码的输出:

#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?

1 个答案:

答案 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 -O4cc有何不同?实际上,引用了Internet术语文件:

  

鼻子恶魔:n。

     

在Usenet组comp.std.c上识别C编译器遇到未定义构造时的任何意外行为的简写。在1992年初对该组进行讨论时,常规评论“当编译器遇到[给定的未定义构造]时,让恶魔飞出你的鼻子是合法的”(这意味着编译器可能会选择任意奇怪的在不违反ANSI C标准的情况下解释代码的方法)。其他人后来提到了“鼻子恶魔”,很快就成立了。原始帖子可通过http://groups.google.com/groups?hl=en&selm=10195%40ksr.com进行网络访问。

所以,我在这里要小心得多。你想让恶魔飞出你的鼻子吗?