iam*_*ind 5 c++ standards pass-by-value return-value-optimization
这个问题在不同的方面(也限于gcc)。我的问题仅适用于未命名的对象。返回值优化 允许更改结果程序的可观察行为。这似乎也在标准中提到。
但是,此“允许”一词令人困惑。这是否意味着RVO 一定会在每个编译器上发生。由于下面的代码更改了RVO,因此可观察到的行为:
#include<iostream>
int global = 0;
struct A {
A(int *p) {}
A(const A &obj) { ++ global; }
};
A foo () { return A(0); } // <--- RVO happens
int main () {
A obj = foo();
std::cout<<"global = "<<global<<"\n"; // prints 0 instead of 2
}
Run Code Online (Sandbox Code Playgroud)
global = 0不管编译器优化和方法大小如何,该程序是否都应打印所有实现foo?
根据标准,程序可以打印0、1或2。C++11中的具体段落是12.8p31,开头为:
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数有副作用。
请注意,这两种复制省略都不是属于as-if规则的优化(as-if 规则要求程序的行为与同一程序的行为一致,就像没有发生优化一样)。该标准明确允许实现生成不同的可观察行为,并且程序员可以让您的程序不依赖于此(或接受所有三种可能的结果)。
注2:任何答案中均未提及1,但这是一种可能的结果。发生了两个潜在的副本,从函数中的局部变量到返回的对象再到 中的对象main,编译器可以忽略一个、一个或两个生成所有三种可能输出的副本。