cout后增量的行为
#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
任何人都可以请解释输出。
cout << i++ << i--
在语义上等同于
operator<<(operator<<(cout, i++), i--); <------arg1--------->, <-arg2->
$ 1.9 / 15-“当调用一个函数(函数是否内联)时,每个expression式或语句的执行之前,每个与任何参数expression式相关的值计算和副作用,或者指定被调用函数的后缀expression式都被sorting在被调用函数的主体中[ 注意:与不同参数expression式相关的值计算和副作用是不确定的。
的C ++ 0x:
这意味着参数arg1 / arg2的评估是没有序列的(两者都没有在另一个之前sorting)。
标准草案中的同一部分还指出,
如果对标量对象的副作用相对于同一个标量对象的另一个副作用或者使用相同标量对象的值进行值计算而言是不确定的,则行为是不确定的。
现在在下面的完整expression式的末尾有一个分号的序列点
operator<<(operator<<(cout, i++), i--); ^ the interesting sequence point is right here
显然,对arg1和arg2的评估导致了标量variables“i”的副作用,正如我们上面所看到的那样,副作用是不确定的。
因此代码有未定义的行为。 那么这是什么意思?
这是标准中“未定义行为”的定义。
允许的未定义的行为范围从完全忽略情况,以不可预知的结果,在翻译或程序执行期间以文档化的方式performance环境特征(不论是否发布诊断消息),终止翻译或执行(发行的诊断消息)。 许多错误的程序结构不会产生未定义的行为; 他们需要被诊断。
你看到与@ DarkDust的回应相关吗?“编译器甚至可以让你的电脑着火:-)”
所以你从这样的代码中得到的任何输出实际上都是未定义行为的可怕领域。
不要这样做。
只有这样的代码defined
是,它有助于OP和我们许多人得到很多票(如果回答正确):)
第二个程序expression式的结果是未定义的。 甚至允许编译器设置你的计算机:-)你不允许在一个序列点内(在这种情况下:从=
到;
)两次修改variables。
编辑:
有关详细解释,请参阅C FAQ ,具体问题3.2 。
未定义的行为,所以可能发生任何事情
添加到其他的答案:
如果您使用的是g++
,则使用-Wsequence-point
选项可以告诉:
$ g++ -Wsequence-point a.cpp a.cpp: In function 'int main()': a.cpp:8: warning: operation on 'i' may be undefined ^^^^^^^^^