【问题标题】:Copy elision and return value optimization versus copy constructor复制省略和返回值优化与复制构造函数
【发布时间】:2014-04-09 03:52:36
【问题描述】:

我一直在阅读有关复制省略和返回值优化如何通过避免调用对象复制构造函数来提高速度的文章。我了解这些机制的工作原理,但我想知道这是否会导致程序的行为与预期不同。

本质上,我的问题是;如果我们编写复制构造函数而不创建作为另一个对象副本的对象会发生什么?换句话说,如果

AClass original;
AClass copy ( original );
// copy == original -> false

比如说,我们有一个这样的类:

// AClass.hpp

struct AClass
{
    static int copyCount;
    int copyNumber;

    AClass():copyNumber(0){}
    AClass( AClass const& original ):copyNumber(++copyCount){} // I think this is the signature for the copy constructor
};


// AClass.cpp

int AClass::count ( 0 );

这显然是一种糟糕的行为,我并不是说我会做这样的事情。然而,重点是存在的;如果我们依赖副本的副作用怎么办?在此示例中,跟踪我们制作了多少副本。我希望优化不应该影响程序的运行方式。但是,复制省略可能会导致以下代码失败:

// Main.cpp

AClass MakeAClass()
{
    return AClass();
}

int main()
{
    AClass copy ( MakeAClass() );

    if ( AClass::copyCount == 1 )
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

当我在没有优化的调试模式下构建时,这可能会返回 0,但是当我打开优化并且从 MakeAClass 的返回直接放在副本上时突然失败,跳过了复制构造函数。

当编译器尝试这些优化以寻找副作用时,是否会进行检查?当您请求副本时,期望代码执行副本是错误的吗?

【问题讨论】:

    标签: c++ optimization return-value-optimization copy-elision


    【解决方案1】:

    是的。如果您的复制构造函数(或移动构造函数或析构函数)有副作用,复制省略可以改变代码的行为。

    这就是重点。如果它不能改变行为,就没有理由在标准中提及它。 as-if 规则已经涵盖了不改变行为的优化。 (1.9/1) 即:

    本国际标准中的语义描述定义了一个 参数化的非确定性抽象机。这个国际 标准对符合的结构没有要求 实施。特别是,他们不需要复制或模仿 抽象机器的结构。相反,符合标准的实现 需要模拟(仅)抽象的可观察行为 机器如下所述。

    标准中明确提到了复制省略,因为它可能违反此规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 2015-07-14
      相关资源
      最近更新 更多