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

Why does the returned value need to be the first declared local for NRVO?

本文关键字:第一个 NRVO 声明 返回 为什么      更新时间:2023-10-16

我的理解是,为了使编译器能够执行命名返回值优化(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();

编辑:谢谢所有回答者帮助我理解这一点,我开始怀疑钱德勒·卡鲁斯在这里的陈述:http://www.youtube.com/watch?v=fHNmRkzxHWs 分钟 32:30 可能具有误导性和/或我只是误解了它。首先对返回变量进行解码似乎并不重要。

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

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

[..]在以下情况下允许对复制/移动操作进行这种省略,称为复制省略(可以合并到 消除多个副本):

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

[..]