首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么g++在这里不启用RVO?

为什么g++在这里不启用RVO?
EN

Stack Overflow用户
提问于 2012-02-15 12:50:35
回答 2查看 1.8K关注 0票数 1

考虑一下测试代码:

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Klass
{
public:
  Klass()
  {
    cout << "Klass()" << endl;
  }

  Klass(const Klass& right)
  {
    cout << "Klass(const Klass& right)" << endl;
  }
};

Klass create(Klass a)
{
  cout << "create(Klass a)" << endl;
  return a;
}

int main()
{
  const Klass result = create(Klass());
}

编撰:

代码语言:javascript
复制
g++ -O3 rvo.cpp   -o rvo

产出如下:

代码语言:javascript
复制
$ ./rvo
Klass()
create(Klass a)
Klass(const Klass& right)

create()**. i期望编译器使用RVO机制,以避免复制函数的返回值和参数,从而避免对每个复制CTOR调用进行编辑。为什么不是这样?**

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-15 13:06:00

您看到的副本是"create“函数中的”返回“语句的副本。RVO不能消除它,因为不能直接构造返回值。你要求“归还”。这里需要一个副本;没有它就无法返回一个对象。

在标准情况下,C++11的下列条件: 12.8/31不符合

在具有类返回类型的函数中的

语句中,当表达式为非易失性自动对象(函数或catch-子句参数以外的)的名称与函数返回类型相同的cv-不限定类型时,可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作。

至于原因,这不是一条武断的规则,从实现的角度来看,这是有意义的,因为这是函数参数不可能做到的:

将自动对象直接构造为函数的返回值

您正在复制函数参数。如果没有内联,则无法删除此副本,因为参数在输入函数之前已经存在,因此不能直接将该对象构造为返回值。

票数 2
EN

Stack Overflow用户

发布于 2012-02-15 13:03:14

该标准只允许在传递临时函数参数的情况下进行复制省略。

您所期望的两种选择如下所示:

[C++11: 12.8/31]:当满足某些条件时,即使对象的复制/移动构造函数和/或析构函数有副作用,也允许实现省略类对象的复制/移动构造器。在这种情况下,实现将省略的复制/移动操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在如果不进行优化就会销毁这两个对象的晚些时候。这种复制/移动操作的省略(称为复制省略)在以下情况下是允许的(可以合并以消除多个副本):

在具有类返回类型的函数中的

  • in语句,当表达式是具有函数返回类型相同的cv-不限定类型的非易失性自动对象(,而不是函数或CATC-子句参数)的名称时,可以通过将自动对象直接构造到函数的返回value
  • in (抛出表达式)中省略复制/移动操作,当操作数是一个非易失性自动对象(函数或CATC-子句参数除外)的名称时,其范围不会扩展到最内封闭的try-块的末尾(如果有),则可以通过将自动对象直接构造到异常object
  • when来省略从操作数到异常对象(15.1)的复制/移动操作--未绑定到引用(12.2)的临时类对象将被复制/移动到具有相同cv-非限定类型的类对象,复制/移动操作可以通过将临时对象直接构造到省略的copy/move
  • when的目标来省略-异常-异常处理程序的声明(第15条)将相同类型的对象声明为异常对象(15.1);如果程序的意义不变,则可以将异常声明作为异常对象的别名来省略复制/移动操作,除非执行异常声明所声明的对象的构造函数和析构函数。

返回值没有发生这种情况,因为非易失性名称是函数参数。

这种情况发生在create参数的构造中,否则您就会看到:

代码语言:javascript
复制
Klass()
Klass(const Klass& right)
create(Klass a)
Klass(const Klass& right)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9293726

复制
相关文章

相似问题

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