1

可能重复:
什么是复制省略和返回值优化?
为什么不调用复制构造函数

为什么在下面的代码中 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。

有任何想法吗?

4

1 回答 1

2

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

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

于 2013-01-04T14:21:58.167 回答