【发布时间】:2013-09-05 13:33:48
【问题描述】:
我对返回值优化的理解是,编译器偷偷传递了将要存储返回值的对象的地址,并对该对象而不是局部变量进行更改。
例如代码
std::string s = f();
std::string f()
{
std::string x = "hi";
return x;
}
变得类似于
std::string s;
f(s);
void f(std::string& x)
{
x = "hi";
}
使用 RVO 时。这意味着函数的接口发生了变化,因为多了一个隐藏参数。
现在考虑以下我从维基百科窃取的案例
std::string f(bool cond)
{
std::string first("first");
std::string second("second");
// the function may return one of two named objects
// depending on its argument. RVO might not be applied
return cond ? first : second;
}
让我们假设编译器会将 RVO 应用于第一种情况,但不会应用于第二种情况。但是函数的接口不会根据是否应用RVO而改变吗?如果函数体f对编译器不可见,编译器如何知道是否应用了RVO以及调用者是否需要传递隐藏地址参数?
【问题讨论】:
-
每个编译器都可以选择以他们想要的任何方式执行此操作,如果在您描述的情况下这对他们来说是个问题,他们可能会选择始终使用 RVO。当您对不同的编译器如何在后台执行此操作感兴趣时,我建议您阅读生成的汇编代码。使用 gcc 资源管理器轻松访问 clang/gcc 生成的程序集。
-
@PlasmaHH 但 RVO 并不总是可行的。
-
这并不意味着调用约定在使用或不使用时会发生变化。看看一些汇编程序是如何做到的。
标签: c++