为什么返回的值必须是NRVO的第一个声明的本地?

时间:2014-11-20 16:52:05

标签: c++ optimization rvo

据我了解,为了使编译器能够进行命名返回值优化(NRVO),必须在函数体中的任何其他值之前声明返回值。我怀疑这可能是由于在异常情况下堆栈展开的顺序,但我不确定。命名返回值必须是在函数体中声明的第一个是什么原因?

class C{};
C f(){
    C ret; //NRVO possible
    return ret;
}
C g(){
    int i;
    C ret;  //NRVO not possible?
    return ret;
}

用例:

auto c = f();
auto c2 = g();

修改 感谢所有回答者帮助我理解这一点,我开始怀疑Chandler Carruth在这里的陈述:http://www.youtube.com/watch?v=fHNmRkzxHWs分钟32:30可能会误导和/或我只是误解了它。首先声明返回变量似乎并不重要。

1 个答案:

答案 0 :(得分:0)

该标准对复制省略方面的变量声明/定义顺序没有要求。请注意,标准说“实施允许”,而不是它应该,应该等。我们可以看到clang and gcc发生了复制省略,但MSVC没有,进一步巩固了这是一个实现定义的优化。

§12.8/ 31描述了复制省略:

  

[..] 在下列情况下(可以合并到以下情况),允许复制/移动操作的省略,称为复制省略   消除多份副本):

     
    

- 在具有类返回类型的函数的return语句中,何时     表达式是非易失性自动对象的名称(其他     比函数或catch子句参数)与之相同     cv-unqualified type作为函数返回类型,copy / move     通过直接构造自动对象可以省略操作     进入函数的返回值

         

- [..]