是否有任何警告让我们知道 GCC 中是否执行了 NRVO/RVO

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

我对编译时功能特别感兴趣。如果有一些特定的#pragma GCC...(可在紧随其后的情况下立即激活诊断)或使用静态断言机制的某些代码,将是很好的。

最佳答案

我不知道任何gcc特定的诊断消息或其他方法可以轻松解决您的任务。如您所知,-fno-elide-constructors将禁用复制/移动省略,因此您将确定至少在这种情况下不会发生(N)RVO。

但是,快速浏览this C++11 working draft第12.8节中的第31段时会指出:



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

#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时,指针比较可能取决于未定义的行为,因为本地自动对象不存在。

进行指针比较会增加麻烦,但是具有编译器独立性的优点。

10-01 20:07