#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
任何人都可以解释输出。
答案 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)
未定义的行为,因此可能发生任何事情