Copy elision是一种简洁的优化技术,在某些情况下依赖于复制省略can actually be faster,而不是“手工”传递参考文献。
因此,我们假设您已经确定了一个关键代码路径,您依赖于编译器为代码路径执行复制省略以获得最佳性能的事实。
但现在您依赖于编译器优化。
是否有任何(编译器特定的,显然)方式确保实际执行复制省略并且如果无法执行复制省略,编译器(或其他工具)会生成警告/错误?
(我正在考虑远远类似于Visual C ++的__forceinline
的东西,如果标记的函数没有被编译器内联,则会产生警告。)
不是真的,除了在复制构造函数中放置assert(false);
。
否则,使用您最喜欢的分析器来衡量应用程序的有趣部分是否足够快。
没有。
但是你可以编写一个等效的,尽管完全不可读的代码:
BigObj f()
{
BigObj x(g());
x.someMethod();
return x;
}
//...
BigObj z = f();
//...
被翻译(复制省略):
void f(BigObj* obj)
{
new(obj) BigObj(g());
obj->someMethod();
}
//...
char z[sizeof(BigObj)];
f((BigObj*)&z[0]);
//...
((BigObj*)&z[0])->~BigObj();
但严重的是,只需编写代码就可以使编译器忽略副本。即只返回一个没有分支的对象:
BigObj f()
{
BigObj x, y;
// use x and y
if(condition)
return x;
else
return y;
// cannot be elided
}
BigObj f()
{
if(condition)
{
BigObj x;
return x;
}
else
{
BigObj y;
return y;
}
// can be elided
}
在C ++ 1z(预计2017年)中,将需要一些案例来保证复制省略:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html
根据communal cppreference.com compiler feature support wiki GCC 7+和Clang 4+确保这一点。
幸运的是,优化方面不应该要求启用更新的语言支持,因为它是纯粹的优化(遵循旧语言标准允许)。
在优化应用时允许复制构造函数不可用可能需要在编译期间启用较新的语言标准,或者使用不要求严格一致性的松散或扩展模式(例如可能是GCC的-fpermissive
)。