【问题标题】:Coping constructor not called when returning by value [duplicate]按值返回时未调用应对构造函数[重复]
【发布时间】:2013-01-04 13:50:05
【问题描述】:

可能重复:
What are copy elision and return value optimization?
why isn’t the copy constructor called

为什么在下面的代码中 gcc 和 clang 都不调用 A 类的复制构造函数,甚至一个 时间(只有一个对象被创建,因为析构函数只被调用一次)。

class A
{
public:
  explicit A()
  {
    std::cout << "A()" << std::endl;
  }
  A(const A& toCp)
  {
    std::cout << "A(const A&)" << std::endl;
  }
  ~A()
  {
    std::cout << "~A()" << std::endl;
  }
  A& operator=(const A& toCp)
  {
    std::cout << "A::operator=" << std::endl;
  }
};

A fun()
{
  A x;
  std::cout << "fun" << std::endl;
  return x;
}

int main()
{
  A u = fun();
  return 0;
}

这段代码的打印输出是:

A()
fun
~A()

我认为它应该调用 2 次复制构造函数(一次用于返回值,一次用于行内A u = fun(7);

我在这段代码中使用了 gcc 和带有 -O0 的 clang。

有什么想法吗?

【问题讨论】:

  • Copy elision 尝试将-fno-elide-constructors 传递给 GCC。

标签: c++ gcc g++ clang


【解决方案1】:

编译器使用复制省略 来避免对函数fun() 的返回值进行复制(或移动)。这是一个标准且微不足道的优化,几乎总是会被调用(取决于编译器及其优化设置)。即使省略的复制(或移动)构造函数会产生副作用(如您的情况,它写入标准输出),编译器也可能会这样做。

注意复制省略不限于 inline 函数,即使函数定义位于不同的编译单元中也会使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2019-08-12
    相关资源
    最近更新 更多