#include <iostream>
using namespace std;
main(){
int i = 5;
cout << i++ << i--<< ++i << --i << i << endl;
}
Run Code Online (Sandbox Code Playgroud)
用g ++编译的上述程序给出了输出:
45555
Run Code Online (Sandbox Code Playgroud)
而以下程序:
int x=20,y=35;
x =y++ + y + x++ + y++;
cout << x<< endl << y;
Run Code Online (Sandbox Code Playgroud)
结果为
126
37
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释输出.
Chu*_*dad 12
cout << i++ << i--
Run Code Online (Sandbox Code Playgroud)
在语义上等同于
operator<<(operator<<(cout, i++), i--);
<------arg1--------->, <-arg2->
Run Code Online (Sandbox Code Playgroud)
$ 1.9/15-"当调用函数时(无论函数是否为内联函数),在执行每个表达式或语句之前,对与任何参数表达式或指定被调用函数的后缀表达式相关联的每个值计算和副作用进行排序在被调用函数的主体中.[ 注意:与不同参数表达式相关的值计算和副作用是无序的.-end note ]
的C++ 0x:
这意味着对参数arg1/arg2的评估未被排序(它们都没有在另一个之前排序).
标准草案中的同一部分也指出,
如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义.
现在,在下面的完整表达式末尾的分号处有一个序列点
operator<<(operator<<(cout, i++), i--);
^ the interesting sequence point is right here
Run Code Online (Sandbox Code Playgroud)
很明显,对arg1和arg2的评估都会对标量变量'i'产生副作用,正如我们上面所看到的,副作用是无效的.
因此代码具有未定义的行为.那是什么意思呢?
以下是标准中"未定义行为"的定义方式:).
允许的未定义行为包括完全忽略不可预测的结果,在翻译或程序执行期间以环境特征(有或没有发出诊断消息)的特定行为,终止翻译或执行(发布时)一条诊断信息).许多错误的程序结构不会产生未定义的行为; 他们需要被诊断出来.
您是否看到与@ DarkDust响应的关联'甚至允许编译器将您的计算机置于火上:-)'
因此,从这样的代码中获得的任何输出实际上都处于未定义行为的可怕领域.
不要这样做.
defined关于此类代码的唯一事情是它有助于OP和我们许多人获得大量投票(如果回答正确):)
| 归档时间: |
|
| 查看次数: |
3871 次 |
| 最近记录: |