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

C++ 为什么返回值必须是NRVO的第一个声明的本地值?,c++,optimization,rvo,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

我的理解是,为了使编译器能够进行命名返回值优化(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();
编辑:
感谢所有回答者帮助我理解这一点,我开始怀疑钱德勒·卡拉斯在这里的陈述:第32:30分钟可能有误导性和/或我只是误解了它。首先声明返回变量似乎并不重要。

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

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

[…]在以下情况下允许省略复制/移动操作,称为复制省略(可组合为 消除多个副本):

-在具有类返回类型的函数中的return语句中,当 表达式是非易失性自动对象(其他)的名称 比函数或catch子句参数)具有相同的 cv不合格类型作为函数返回类型,复制/移动 通过直接构造自动对象,可以省略操作 输入函数的返回值

-[……]


可能有一些编译器施加了这个限制,但一般来说,您的理解是有缺陷的——变量定义顺序不能启用/禁用NRVO。您测试过这个假设吗?如果是,使用哪种编译器?这可能会有所帮助