按值返回时未应用的应对构造函数

时间:2013-01-04 13:50:06

标签: c++ gcc g++ clang

  

可能重复:
  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和clang -O0。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

编译器使用 copy elision 来避免复制(或移动)函数fun()的返回值。这是一个标准和简单的优化,几乎总是会被调用(取决于编译器及其优化设置)。即使被删除的复制(或移动)构造函数会产生副作用(如在您的情况下,它写入stdout的地方),编译器也可以这样做。

note 复制省略不仅限于inline个函数,但即使函数定义位于不同的编译单元中,也会使用它。