首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC NRVO/RVO警告

GCC NRVO/RVO警告
EN

Stack Overflow用户
提问于 2013-12-19 05:41:01
回答 1查看 3.4K关注 0票数 21

是否有任何警告可以让我们知道NRVO/RVOGCC中是否执行过?

我发现-fno-elide-constructors关闭NRVO/RVO,但NRVO/RVO有其自身的发生条件,有时不发生。有必要知道NRVO/RVO是否发生了理解,何时发生额外的复制构造。

我对编译时特性特别感兴趣。如果有一些特定的#pragma GCC... (它会立即激活诊断本身)或使用静态断言机制的东西,那就太好了。

EN

回答 1

Stack Overflow用户

发布于 2014-01-20 18:26:44

我不知道任何gcc的具体诊断信息或其他方法,很容易解决您的任务。正如您已经发现的,-fno-elide-constructors将禁用复制/移动省略,因此您将确信至少在这种情况下不会发生(N)RVO。

然而,这份C++11工作草案第12.8节第31段指出:

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

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

..。

  • 当没有绑定到引用 (12.2)的临时类对象被复制/移动到具有相同cv非限定类型的类对象时,可以通过将临时对象直接构造到省略的复制/移动的目标中来省略复制/移动操作。

..。

当复制/移动省略发生时,本地auto对象与临时(返回)对象相同,后者又与“存储”对象(其中存储返回值)相同。因此,本地自动对象与存储对象相同,这意味着指针比较将等于true。一个简单的例子说明了这一点:

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

std::vector<int> testNRVO(int value, size_t size, const std::vector<int> **localVec)
{
   std::vector<int> vec(size, value);

   *localVec = &vec;

   /* Do something here.. */

   return vec;
}

int main()
{
   const std::vector<int> *localVec = nullptr;

   std::vector<int> vec = testNRVO(0, 10, &localVec);

   if (&vec == localVec)
      std::cout << "NRVO was applied" << std::endl;
   else
      std::cout << "NRVO was not applied" << std::endl;
}

启用/禁用-fno-elide-constructors将按预期更改打印的消息。注意:在最严格的意义上,指针比较可能取决于(N)RVO不发生时的未定义行为,因为本地auto对象是不存在的。

做指针比较会增加cruft,但具有编译器无关的优点.

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

https://stackoverflow.com/questions/20674231

复制
相关文章

相似问题

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