首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回值优化在C++中可靠吗?

返回值优化在C++中可靠吗?
EN

Stack Overflow用户
提问于 2014-11-25 19:22:34
回答 2查看 105关注 0票数 0

正如这个wiki页面所说的(代码如下所示),返回值优化是C++编译器允许的,但仍然取决于实现。为了减少复制的成本,建议手动优化它(将函数的对象赋给引用,如const C& obj = f();),还是让编译器在实践中进行这种优化?

代码语言:javascript
复制
#include <iostream>

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

编辑:将更改更新为常量引用。

EN

回答 2

Stack Overflow用户

发布于 2014-11-25 19:30:25

您不能(可移植地)使用临时返回值来初始化非常数引用,因此肯定不推荐这样做。

使用它初始化const引用对返回表达式的值的复制/移动是否可以省略没有任何影响;尽管它会从返回值中消除用于初始化变量的名义上的复制/移动,无论是否已经省略。当然,这与初始化(非引用)变量不同,因为您不能修改它。

实际上,任何具有良好优化器的编译器都会省略复制,并在允许的情况下移动到任何地方。如果你没有使用一个像样的优化器,那么无论如何你也不能期望有像样的性能。

票数 3
EN

Stack Overflow用户

发布于 2014-11-25 22:03:16

要手动确保不会获得对象的任何冗余副本,您需要做的工作比到目前为止所做的要多一点。之前我回答说这是不可能的,但我错了。此外,使用const&可能不允许对返回值执行某些您希望允许的操作。如果你需要手动进行优化,我会这么做:

代码语言:javascript
复制
#include <iostream>

struct S {
  S()
  { std::cout << "default constructor\n"; }
  S(const S &)
  { std::cout << "copy constructor\n"; }
  S(S &&)
  { std::cout << "move constructor\n"; }
  ~S()
  { std::cout << "destructor\n"; }
};

S f() { return {}; }

int main() {
  auto&&s = f();
  std::cout << "main\n";
}

这将打印"default destructor“,然后是"main",然后是"destructor”。无论是否发生任何复制省略,这都是输出。在main中,s是一个命名引用,所以它是一个左值,而不是const-qualified。你可以用它做任何你本来可以做的事情。

鉴于事实证明,在这样的情况下避免依赖复制省略相当容易,只要您从一开始就注意到它,如果您不得不担心其他编译器不执行复制省略,那么您的努力可能是值得的。大多数编译器都能做到这一点,如果编译器不能做到这一点,它很有可能会遇到其他更大的问题,所以有一个很好的理由不用担心这个问题。

然而,同时,复制省略在某种程度上是不可靠的:即使是当前的优化编译器也不总是执行它,原因很简单,在某些情况下,复制省略是有意义的,但标准不允许,或者对于特定的实现是不可能的。强迫自己编写不依赖于复制省略的代码意味着您不能陷入这种情况。

也就是说,在某些情况下,复制遗漏只能通过优化编译器来实际消除,因此您可能别无选择,只能依赖它:

假设我们将void m();添加到S的定义中。假设我们现在编辑f

代码语言:javascript
复制
S f() {
  S s;
  s.m();
  return s;
}

这就更难重写成一种保证没有冗余副本的形式。然而,同时,副本是不必要的,这可以很容易地从以下事实中确定:使用GCC (可能还有其他编译器),默认情况下,不会创建副本。

我最后的结论是,对于不执行RVO的编译器来说,它可能不值得优化,但值得仔细考虑到底是什么让它工作,并以这样一种方式编写代码,即RVO不仅是可能的,而且成为编译器很可能做的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27125304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档