【发布时间】:2011-12-15 15:32:00
【问题描述】:
原始代码
#include <iostream>
int global;
struct A
{
A(){}
A(const A&x){
++global;
}
~A(){}
};
A foo()
{
A a;
return a;
}
int main()
{
A x = foo();
std::cout << global;
}
在支持命名返回值优化的优化编译器上,输出将是 0。
当我将foo 的定义更改为
A foo()
{
{
A a;
return a;
}
}
我得到1 作为输出,即复制 c-tor 被调用一次。可能的原因是什么?引入虚拟作用域会完全改变代码的行为。我错过了什么?
我在 g++ 编译器上对其进行了测试。这里有任何编译器人员可以以某种特定于实现的方式解释该场景吗?
编辑
我在 clang 上对其进行了测试,即使在第二种情况下,它也优化了对复制 c-tor 的调用。
Andrew Pinski(gcc 专家)证实这确实是 g++ 错过优化的一个案例。
【问题讨论】:
-
这样的优化可以应用或不应用在编译器的心血来潮。试图对它们进行推理是……愚蠢的。没有?
-
因为编译器需要非常严格地应用优化。如果其任何预条件失败,则无法应用优化。对人类来说,它可以在这里做到这一点似乎很明显,但是在一般情况下添加额外的范围会增加一些复杂的预条件检查失败。这里唯一好的答案是@Tomalak,因为优化是由编译器选择完成还是不完成(启发式)。
-
@Prasoon:好的。
Output would be 0 on an optimized compiler向我暗示您希望在 任意 优化的编译器上获得可重现的结果,而不是在您的 PC 上仅运行一次。 -
@Prasoon:它询问 RVO 是否“普遍保证”,给出的答案是“否”。一周后,你发布了这个,显然很惊讶你的 RVO 在某种情况下消失了。大声笑!
-
@PrasoonSaurav:(a) RVO 是 跨实现行为。 (b) 那太糟糕了;我发现幽默感对于富有成效的生活至关重要。
标签: c++ optimization scope g++ nrvo