Copy elision是一种简洁的优化技术,在某些情况下依赖于复制省略can actually be faster,而不是“手动”传递引用。
因此,我们假设您已经确定了一个关键代码路径,您依赖于编译器为代码路径执行复制省略以获得最佳性能。
但现在你依赖于编译器优化。
是否有任何(编译器特定的,显然)方式确保实际执行复制省略并且如果无法执行复制省略,编译器(或其他工具)会生成警告/错误?
(我正在考虑与Visual C ++的__forceinline
远程类似的东西,如果编译器没有内联标记的函数,则会产生警告。)
答案 0 :(得分:4)
没有
但你可以编写一个等效的,但完全不可读的代码:
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
}
答案 1 :(得分:4)
不是这样,除了在复制构造函数中放置assert(false);
。
否则,请使用您最喜爱的探查器来衡量应用程序中有趣的部分是否足够快。
答案 2 :(得分:2)
在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&# 39; s -fpermissive
)。