当-fno-elide-constructors选项与clang或gcc一起使用,并且按值返回一个对象时,我对C ++的正确语义感兴趣。如果我有这个功能并调用它:
X foo()
{
X x(0);
X y(1);
X z;
if (rand() > 50)
z = x;
else
z = y;
return z;
}
X z = foo();
然后我可以看到X的复制构造函数只被调用一次。但是,如果我稍微修改一下这个函数:
X foo()
{
X x(0);
X y(1);
if (rand() > 50)
return x;
else
return y;
}
X z = foo();
然后复制构造函数被调用两次。从实现的角度来看,我可以看到在后一种情况下这可能是什么必要的,但我发现令人困惑的是,即使我们明确地关闭了复制省略,似乎还有不同数量的复制构造函数被调用关于如何实现该功能。
是否有标准部分涵盖此行为?
答案 0 :(得分:2)
在第一种情况下,您会看到return value optimization,这基本上意味着编译器在函数的返回槽中分配z
。这在第二种情况下不起作用,所以你在那里看到另一个副本。复制省略有所不同:http://en.wikipedia.org/wiki/Copy_elision并不适用于此处。标准只是说这样的东西,编译器可以省略不必要的副本,它允许但不需要这些优化。