可能重复:
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。
有什么想法吗?
答案 0 :(得分:2)
编译器使用 copy elision 来避免复制(或移动)函数fun()
的返回值。这是一个标准和简单的优化,几乎总是会被调用(取决于编译器及其优化设置)。即使被删除的复制(或移动)构造函数会产生副作用(如在您的情况下,它写入stdout的地方),编译器也可以这样做。
note 复制省略不仅限于inline
个函数,但即使函数定义位于不同的编译单元中,也会使用它。