【问题标题】:Can a C++ compiler perform RVO for a named const variable used for the return value?C++ 编译器能否为用于返回值的命名 const 变量执行 RVO?
【发布时间】:2019-05-17 23:23:23
【问题描述】:

这个问题是一个相关问题shown here的轻微变体。

在 C++17 中,我有一个局部变量,我想将其设为 const,以证明它在根据 Scott Meyers Effective C++use const whenever possible 提出的第 3 项建议创建后未经修改:

#include <string>

std::string foo()
{
    const std::string str = "bar";

    return str;
}

int main()
{
    std::string txt = foo();
}

编译器能否为txt 执行(命名)返回值优化,即使str 的类型与foo 的返回类型因常量差异而不同?

【问题讨论】:

  • 语义上,return str 创建了一个对象,它是str 的副本,因此 RVO 是可能的。是否可以执行 NVRO 值得怀疑,因为返回的对象需要与 str 不同。但是,如果函数与调用者在同一个编译单元中,则根据编译器执行的分析,它可以内联然后完全消除函数调用,并将std::string txt = foo()替换为std::string txt("bar")的名义等效项。
  • IANALL 但肯定const 必须应用于变量的范围以保证str 在调用foo() 期间保持不变。否则破坏如何运作?

标签: c++ c++17 return-value-optimization nrvo


【解决方案1】:

命名返回值优化是通过在 C++17 中 [class.copy.elision] 中指定的复制省略启用的。这里的相关部分是[class.copy.elision]/1.1

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数有副作用。 […]

  • 在具有类返回类型的函数中的return 语句中,当表达式是非易失性自动对象的名称时(除了函数参数或由处理程序的异常声明引入的变量( [except.handle])) 与函数返回类型相同的(忽略cv-qualification),可以通过将自动对象直接构造到函数调用的返回对象中来省略复制/移动操作

[…]

强调我的。因此,允许编译器在此处执行优化。而a quick test 似乎会验证编译器实际上会在此处执行此优化……

请注意,const 可能仍然存在问题。如果编译器不执行复制省略(仅允许,但不保证在这里发生;即使在 C++17 中,因为 return 语句中的表达式不是纯右值),const 通常会阻止对象而是被移出(通常不能从const 对象移出)……

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 2020-11-07
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 2023-03-25
    • 2017-05-29
    相关资源
    最近更新 更多