msc*_*msc 23 c++ undefined-behavior c++11 c++17
我读到了关于未定义行为的答案,我看到以下声明:
++++++i; // UB, parsed as (++(++(++i)))
Run Code Online (Sandbox Code Playgroud)
我认为这不是未定义的行为.我有一个疑问,它在C++中真的是UB吗?如果是,那怎么样?
此外,我制作程序并使用g++ prog.cpp -Wall -Wextra -std=gnu++1z -pedantic命令编译,它没有任何警告工作正常.它给出了预期的输出.
#include <iostream>
using namespace std;
int main()
{
int i = 0;
cout<<++++++i<<endl;
}
Run Code Online (Sandbox Code Playgroud)
use*_*001 37
在C++ 03中,它是未定义的行为.在C++ 11中它不是.各种预增量之间没有序列点.如果i是用户定义的类型,那么它将是明确定义的行为,因为那时会有一个函数调用(一个序列点).
在C++ 11中,序列点的概念被替换为之前/之后的序列.缺陷637(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637)提供了一个先前未定义的构造变得良好定义(i = ++i + 1)的示例.
要理解为什么它不是未定义的行为,让我们看看我们需要的部分.++i相当于i = i + 1(除了i仅评估一次).另外,如果我们替换i = i + 1用inc,++(i = i + 1)变成inc = inc + 1.
[expr.ass]指出:
在所有情况下,在右和左操作数的值计算之后,以及在赋值表达式的值计算之前,对赋值进行排序.
因此,在i = i + 1计算值之前对赋值进行排序inc; 但是,在计算值之后,对赋值进行inc = inc + 1排序.没有未定义的行为,因为分配是按顺序排序的.inc
有时行为是不确定的,即使很难想象它会如何被错误处理.但是在C++之前的版本11中,这是未定义的,因为同一个对象被多次修改而没有指向插入的序列.
可以想象一个编译器通过合并所有修改来"优化"代码i.因此,每个增量都会增加原始值.但那不是重点.如果标准这样说,UB是UB.我们是否可以想象它可能失败的方式并不重要.
| 归档时间: |
|
| 查看次数: |
1417 次 |
| 最近记录: |