Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why copy constructor is always called when return by value

Tags:

c++

When a function returns an object by value, it will call the copy constructor to create a temporary (unless RVO is applied). That temporary will then be destroyed after use, e.g.

MyClass function_return_by_value(MyClass par)
{
    return par;
}
MyClass b;
MyClass a = function_return_by_value(b);  // (1)

But why do we need to create such a temporary if it is not used at all? For example, why the following code is not "optimized" by the compiler to skip the temporary creation and destroy?

MyClass b;
function_return_by_value(b);  // (2)

In (1), the return value is assigned to another variable and RVO is likely to apply. But in (2), there is nothing to receive the return value, why is there no optimization take place? I have tried gcc 4.8.4 and vc++ 2015, copy constructor of MyClass is called twice for (2) in both compilers. Why do compiler makers all decide to make a temporary then destroy it even if the temporary is not used at all? Why can't they avoid this?

like image 840
james Avatar asked Jun 22 '26 19:06

james


2 Answers

The side-effects of a copy can be removed by the compiler when RVO has elided it (which is fairly controversial in itself), but the entire existence of an object cannot be simply removed from your program by an optimising compiler, as long as constructing and/or destroying it has side effects.

That would allow the following program to output nothing, which is very clearly wrong:

#include <iostream>

struct A
{
   A() { std::cout << "Booyah\n"; }
};

int main()
{
   A a;
}
like image 159
Lightness Races in Orbit Avatar answered Jun 25 '26 10:06

Lightness Races in Orbit


I have tried gcc 4.8.4 and vc++ 2015, copy constructor of MyClass is called twice for (2) in both compilers.

Because that is how it is supposed to work!

Really, for the case where you want this to be optimized, there's the reference mechanism in C++; in your case it must not be optimized away, because "I checked" implies that you relied on a side effect of the constructor to show you it's being called; how should the compiler know you don't functionally need that side effect?

like image 30
Marcus Müller Avatar answered Jun 25 '26 12:06

Marcus Müller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!