Reputation: 143
In the following code, it prints out two different memory locations. This makes sense to me as I am returning by value.
#include <iostream>
using namespace std;
class Foo {
public:
Foo () {}
// Foo (const Foo &) { cout << "Copy con" << endl; }
};
Foo test () {
Foo foo;
cout << &foo << endl;
return foo;
}
int main () {
Foo foo = test();
cout << &foo << endl;
}
However, if I uncomment the copy constructor in the above code and run it again, it outputs the same memory location twice. Why? It doesn't print out "Copy con" at all, so I know the copy constructor isn't being called. It seems that the mere presence of a copy constructor causes some sort of optimisation, even though it isn't called.
I'm compiling with a "g++ -Wall test.cpp -o test" on GCC 4.6.3.
Upvotes: 4
Views: 149
Reputation: 29966
This is a result of return value optimization. Basically, your compiler omits the costly copy operation resulted from the return statement, even though the copy constructor has side effects.
The reasoning behind this is that returning a complex object is costy. Instead of wasting the time on copying, the compiler secretly creates a hidden object in the caller's stack frame, and passes the reference to that hidden object to the called function, and the function's return value is copied directly into that hidden object.
The C++ standart states this explicitly (ISO-IEC 14882:2011 12.8 para. 31):
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects.
Upvotes: 2