Rus*_*lan 8 c++ undefined-behavior copy-elision
考虑以下代码:
#include <iostream>
struct Test
{
int x;
int y;
};
Test func(const Test& in)
{
Test out;
out.x=in.y;
out.y=in.x;
return out;
}
int main()
{
Test test{1,2};
std::cout << "x: " << test.x << ", y: " << test.y << "\n";
test=func(test);
std::cout << "x: " << test.x << ", y: " << test.y << "\n";
}
Run Code Online (Sandbox Code Playgroud)
人们会期望这样的输出:
x: 1, y: 2
x: 2, y: 1
Run Code Online (Sandbox Code Playgroud)
这确实是我得到的.但由于复制省略,可能out在内存中的同一位置in并导致最后一行输出x: 2, y: 2?
我试着用gcc和铿锵既编译-O0和-O3,结果却看起来像预期.
这是格式良好的代码,优化不能破坏格式良好的代码,因为它会违反as-if 规则。这告诉我们:
\n\n\n\n\n特别是,它们不需要复制或模拟抽象机的结构。相反,需要一致的实现来模拟(仅)抽象机的可观察行为,如下所述
\n
复制省略除外:
\n\n\n\n\n[...]允许省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数有副作用。[。 ..]
\n
但仍然必须遵循排序规则,如果我们查看标准草案,我们会发现赋值是在第 5.17 节评估左右操作数之后进行排序的:
\n\n\n\n\n在所有情况下,赋值都在右操作数和左操作数的值计算之后、赋值表达式的值计算之前进行排序
\n
我们知道,相对于其他未通过 1.9 节中的函数调用专门排序的求值,函数体的排序是不确定的:
\n\n\n\n\n调用函数(包括其他函数调用)中的每个计算在被调用函数体执行之前或之后没有明确排序的,都相对于被调用函数的执行不确定地排序 9
\n
不确定顺序意味着:
\n\n\n\n当 A 在 B 之前排序或 B 在 A 之前排序时,评估 A 和 B 的顺序是不确定的,但未指定是哪一个。[ 注意:不确定顺序的评估不能重叠,但可以先执行其中一个。\xe2\x80\x94结束注]
\n
| 归档时间: |
|
| 查看次数: |
402 次 |
| 最近记录: |