#include <stdio.h>
int main()
{
int y = 1;
if (y & (y = 2))
printf("true \n");
else
printf("false \n");
return 0;
}
输出:
true
在此程序中存在未定义的行为。输出始终为true
。我试过几个编译器。任何人都可以解释为什么它一直是true
吗?
答案 0 :(得分:4)
因为观察行为不是定义的行为。您正在使用的编译器(仅通过观察)执行以下操作:
y = 2
y
结果为(2 & 2)
, true 。问题是,1-2的顺序,然后3不是标准定义的。它可以很容易就是这样:
y
y = 2
结果为(1 & 2)
, false
或者它可能完全不同。不是所有编译器都会做第一个,你不能假设因为你使用的编译器做了,他们所有都会。你也不能假设因为他们这样做而且你观察到了这种行为,因此它被定义了;事实并非如此。 编译器没有定义行为;标准确实如此,编制者有义务遵守。
注意:在这个定义时代存在一个漏洞,但它不是不是标准,甚至它也是由标准松散定义的。你会发现标准中的区域是“实现定义的”。在这种情况下,该标准明确指出了这些分歧区域。在这种情况下,您应该咨询您的实现,以获得关于期望行为的明确结论,并且这样做准备好接受这样的事实:这种行为只能在实现的范围内依赖。这(你的样本)不这样的漏洞例外。
我的clang 3.5 rig 似乎(通过我的观察)来运行第二个序列,而不是第一个序列,我可以走你的路,并假设我尝试的所有编译器(其中一个) )表现得像那样,因此它被定义为如此。我会错误地这样做,就像你的假设一样。
未定义的行为就是这样; 未定义
答案 1 :(得分:0)
您尝试在序列点之间多次修改y的值。如何处理该行为没有标准的方法。所以:
i = i++; // gives undefined behavior also
瓦尔特
答案 2 :(得分:-2)
是的,代码将始终返回True
因为任何条件语句中的任何非零值都是True
(上面的C-99)或1
(C-99)
if (y & (y = 2))
printf("true %d\n");
在if条件2中,首先分配给y,然后按2分别按2分配。 即0010&amp;因此,它将返回0010。
所以现在你有:
if(2) //Any non-zero value is true
printf("true %d\n");