当我总是得到相同的结果时,为什么这种未定义的行为?

时间:2010-04-12 19:15:39

标签: c++

我最近在这个网站上遇到过关于C ++序列点的问题 这段代码将输出什么:

int c=0;
cout << c++ << c;

回答输出未定义且&lt;&lt;不是序列点,但我仍然想知道为什么它是未定义的,即使我编译25次,它仍然总是打印01?

4 个答案:

答案 0 :(得分:8)

“未定义”意味着标准没有指定在那种情况下必须发生的事情,因此根据定义,编译器所做的任何事情都是正确的。如果它总是打印01,那很好。如果每次运行时都打印出不同的数字,那也没关系。如果它导致猴子飞出你的鼻子(如illustrated here),那也没关系。

您可能不这么认为,但如果发生这种情况,编译器编写者就会陷入困境。

[编辑:在评论中已经指出,该标准是“鼻子恶魔”,而不是“鼻猴”。我为任何意外的混乱道歉。任何意图混淆我为此感到自豪并且不为此道歉。 :-)]

答案 1 :(得分:6)

你问:

  

为什么即使我编译它也是如此   25次仍然打印01

答案是因为编译器基本上(但不是完全)确定性 - 给定相同的输入,它们将产生相同的输出。在机器代码方面。并且该机器代码也是确定性的,因此始终输出“01”。另一个C ++编译器虽然可能以类似的确定性方式生成每次都生成“10”的机器代码。

答案 2 :(得分:5)

因为始终打​​印01是您的程序允许的行为之一。

答案 3 :(得分:1)

cout<<c++<<c; 

让我们将其分解为各个部分:

int c1 = c;        // A
c = c + 1;         // B
int c2 = c;        // C
cout << c1 << c2;  // D

现在,我们对这些操作的订单了解多少? A必须在B之前,A&amp; C必须在D之前。在这些限制内,它们可以是任何顺序。您可能希望它们作为A-B-C-D执行,但它们可以像A-C-D-B一样有效地执行。甚至是C-A-D-B。事实上,将它们作为A-(B&amp; C)-D执行是合法的,其中B&amp; C在不同的CPU上同时执行(这会导致内存访问错误,这就是为什么这是未定义的而不仅仅是实现定义的行为)