带有-fno-elide-构造函数的临时对象

Temporary objects with -fno-elide-constructors

本文关键字:临时对象 构造函数 -fno-elide- 带有      更新时间:2023-10-16

我对在clang或gcc中使用-fno-elide-constructors选项并且按值返回对象时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();

则调用复制构造函数两次。从实现的角度来看,我可以看到在后一种情况下这是多么必要,但我发现令人困惑的是,似乎即使我们显式地关闭了复制省略,也会根据函数的实现方式调用不同数量的复制构造函数。

标准中是否有一个部分涵盖了这种行为?

在第一种情况下,您看到返回值优化,这基本上意味着编译器在函数的返回槽中分配z。这在第二种情况下不起作用,所以你在这里看到了另一个副本。复制省略是不同的:http://en.wikipedia.org/wiki/Copy_elision,并不适用于这里。标准只是说,像这样的东西编译器可以自由地省略不必要的副本,这允许但不需要这两种优化。