宏命名错误,但这只是一个红鲱鱼。这两个语句扩展为:
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上通过网络访问。
所以,在这里我会更加小心。你想让恶魔从你的鼻子里飞出来吗?