cout中后增量的行为

时间:2010-10-21 10:13:32

标签: c++

#include <iostream>
using namespace std;

main(){

int i = 5;

cout << i++ << i--<< ++i << --i << i << endl;


}

用g ++编译的上述程序给出了输出:

45555

以下程序:

int x=20,y=35;

x =y++ + y + x++ + y++;

cout << x<< endl << y;

将结果显示为

126

37

任何人都可以解释输出。

4 个答案:

答案 0 :(得分:12)

cout << i++ << i--

在语义上等同于

operator<<(operator<<(cout, i++),   i--);
           <------arg1--------->, <-arg2->
  

$ 1.9 / 15-“调用函数时   (无论功能是否   内联),每个值计算和   副作用与任何相关   参数表达式,或者与   后缀表达式指定   被称为函数,之前是排序的   执行每个表达式或   在被召唤的身体中的陈述   功能。 [注意:值计算   与...相关的副作用   不同的参数表达式   未测序。 - 注意]

的C ++ 0x:

这意味着对参数arg1 / arg2的评估未被排序(它们都没有在另一个之前排序)。

标准草案中的同一部分也指出,

  

如果对标量对象产生副作用   没有相对于另一个人   对同一标量物体的副作用   或者使用该值计算值   同一个标量对象,   行为未定义。

现在在

下面的完整表达式末尾的分号处有一个序列点
operator<<(operator<<(cout, i++), i--);
                                      ^ the interesting sequence point is right here

很明显,对arg1和arg2的评估会对标量变量'i'产生副作用,正如我们上面所看到的,副作用是没有顺序的。

因此代码具有未定义的行为。那是什么意思呢?

以下是标准中“未定义行为”的定义方法。

  

允许的未定义行为范围   完全忽视这种情况   结果不可预测   在翻译或节目期间表现   以书面形式执行   环境的特征   (无论是否发行   诊断消息),终止a   翻译或执行(与...   发布诊断消息)。   许多错误的程序结构都可以   不产生未定义的行为;他们   需要被诊断出来。

您是否看到与@ DarkDust响应的相关性'甚至允许编译器将您的计算机置于火上: - )'

因此,从这样的代码中获得的任何输出都是处于未定义行为的可怕领域。

不要这样做。

只有defined关于此类代码的事情是它有助于OP和我们中的许多人获得大量投票(如果回答正确):)

答案 1 :(得分:4)

第二个程序表达式的结果是未定义的。甚至允许编译器设置您的计算机:-)您不允许在一个序列点内修改变量两次(在这种情况下:从=;)。

修改

有关详细说明,请参阅the C FAQ,特别是question 3.2

答案 2 :(得分:3)

添加到其他人的答案:

如果您使用g++,请使用-Wsequence-point选项告知:

$ g++ -Wsequence-point a.cpp
a.cpp: In function ‘int main()’:
a.cpp:8: warning: operation on ‘i’ may be undefined
                                          ^^^^^^^^^

答案 3 :(得分:2)

未定义的行为,因此可能发生任何事情