是否有任何警告可以让我们知道NRVO/RVO在GCC中是否执行过?
我发现-fno-elide-constructors关闭NRVO/RVO,但NRVO/RVO有其自身的发生条件,有时不发生。有必要知道NRVO/RVO是否发生了理解,何时发生额外的复制构造。
我对编译时特性特别感兴趣。如果有一些特定的#pragma GCC... (它会立即激活诊断本身)或使用静态断言机制的东西,那就太好了。
发布于 2014-01-20 18:26:44
我不知道任何gcc的具体诊断信息或其他方法,很容易解决您的任务。正如您已经发现的,-fno-elide-constructors将禁用复制/移动省略,因此您将确信至少在这种情况下不会发生(N)RVO。
然而,这份C++11工作草案第12.8节第31段指出:
当满足某些条件时,即使对象的复制/移动构造函数和/或析构函数有副作用,也允许实现省略类对象的复制/移动构造。在这种情况下,实现将省略的复制/移动操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在如果不进行优化就会销毁这两个对象的稍后时间。这种复制/移动操作的省略(称为复制省略)在以下情况下是允许的(可以组合使用以消除多个副本):
..。
..。
当复制/移动省略发生时,本地auto对象与临时(返回)对象相同,后者又与“存储”对象(其中存储返回值)相同。因此,本地自动对象与存储对象相同,这意味着指针比较将等于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不发生时的未定义行为,因为本地auto对象是不存在的。
做指针比较会增加cruft,但具有编译器无关的优点.
https://stackoverflow.com/questions/20674231
复制相似问题