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?
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;
}
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With