有没有warning,这让我们知道是否NRVO/RVO执行与否,在GCC?
我找到-fno-elide-constructors
关掉NRVO/RVO, but NRVO/RVO有其发生的条件,有时不发生。有必要知道是否NRVO/RVO当额外的复制构造发生时,就会发生理解。
我对编译时功能特别感兴趣。如果有一些具体的就好了#pragma GCC...
(它会立即激活诊断)或使用静态断言机制的东西。
我不知道有任何 gcc 特定的诊断消息或其他方法可以轻松解决您的任务。正如您所发现的,-fno-elide-constructors
将禁用复制/移动省略,因此您可以确定至少在这种情况下不会发生 (N)RVO。
然而,快速浏览一下第 12.8 节中的第 31 段这个 C++11 工作草案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf指出:
当满足某些标准时,允许实施省略
类对象的复制/移动构造,即使复制/移动
对象的构造函数和/或析构函数有副作用。在
此类情况,实现处理源和目标
省略复制/移动操作作为简单的两种不同的引用方式
对同一个对象,并且该对象的销毁发生在
当这两个物体被摧毁的时候
没有优化。这种复制/移动操作的省略,
称为复制省略,在以下情况下允许
(可以组合起来消除多个副本):
-
在具有类返回类型的函数的 return 语句中,当表达式是非易失性自动对象的名称时(其他
比函数或 catch 子句参数)具有相同的 cv-unqualified
type 作为函数返回类型,复制/移动操作可以是
通过直接将自动对象构造到
函数的返回值
...
-
当尚未绑定到引用的临时类对象时(12.2)将被复制/移动到具有相同的类对象
cv-非限定类型,复制/移动操作可以省略
将临时对象直接构造到目标中
省略复制/移动
...
当复制/移动省略发生时,本地自动对象与临时(返回)对象相同,而临时(返回)对象又与“存储”对象(存储返回值的位置)相同。因此本地自动对象与存储对象相同,这意味着指针比较将等于 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 对象不存在。
进行指针比较会增加麻烦,但具有编译器独立性的优点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)