0

我的理解是,要让编译器能够进行命名返回值优化 (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 可能具有误导性和/或我只是误解它。首先声明返回变量似乎并不重要。

4

1 回答 1

0

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

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

[..]这种复制/移动操作的省略,称为复制省略,在以下情况下是允许的(可以结合起来消除多个副本):

— 在具有类返回类型的函数的 return 语句中,当表达式是具有与函数返回类型相同的 cv 非限定类型的非易失性自动对象(函数或 catch 子句参数除外)的名称时, 可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作

[..]

于 2014-11-20T18:17:58.177 回答