是否有任何警告让我们知道 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时,指针比较可能取决于未定义的行为,因为本地自动对象不存在。进行指针比较会增加麻烦,但是具有编译器独立性的优点。