相关疑难解决方法(0)

什么是复制省略和返回值优化?

什么是复制省略?什么是(命名)返回值优化?他们意味着什么?

它们会在什么情况下发生?有什么限制?

c++ optimization c++-faq return-value-optimization copy-elision

350
推荐指数
4
解决办法
7万
查看次数

移动返回对象的构造函数会破坏C ++ 98代码?

标准不需要编译器执行返回值优化(RVO),但是从C ++ 11开始,必须移动结果。

看来,这可能会将UB引入到/破坏代码中,这在C ++ 98中是有效的。

例如:

#include <vector>
#include <iostream>

typedef std::vector<int> Vec;
struct Manager{
    Vec& vec;
    Manager(Vec& vec_): vec(vec_){}
    ~Manager(){
        //vec[0]=42; for UB
        vec.at(0)=42;
    }
};

Vec create(){
    Vec a(1,21);
    Manager m(a);
    return a;
}

int main(){
    std::cout<<create().at(0)<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当使用gcc(或与此相关的clang)进行编译时(为了简化示例,-O2 -fno-inline -fno-elide-constructors我正在使用std::vector这些build-option。如果没有这些选项以及手工类和更复杂的create功能,则可能会触发相同的行为)对于C ++ 98(-std=c++98)一切正常:

  1. return a;触发复制构造函数,它保持a原样。
  2. 的Destructor m称为(必须在a被销毁之前发生,因为它m是在之后构造的a)。a在析构函数中访问是没有问题的。
  3. 的析构a函数称为。

结果与预期的一样:21已打印(此处为live)。 …

c++ gcc rvo c++11

8
推荐指数
1
解决办法
328
查看次数