return value optimization

I got a surprise when I run the program below with g++ (mingw port).

* returnLocalVar() should return by value, by calling the copy constructor, but copy constructor didn't get called.
* localCat object should be destructed when it goes out of scope at end of the function, but no it was kept alive till end of main()
* ret is a local variable in main(), not a reference, so i expect ret to be a copy of localCat, with a separate address, but no they 2 variables have the same address.

#include
#define S(x) std::cout<<#x" address =\t"<<&x<<"\n";
using namespace std;
struct CAT {
    CAT() {
        cout < no-arg constructor with addr = ” << this << "\n";
    } // default constructor
    ~CAT() {
        cout << this << " Destructor called!\n";
    }
    CAT(const CAT& rhs) {
        cout < copy constructor ” << this << " <- " << &rhs << "\n";
    }
};
CAT returnLocalVar() {
    CAT localCat;
    cout << "leaving returnCat\n";
    return localCat;
    // localCat is not destructed if result is assigned
}
int main() {
    CAT ret = returnLocalVar();
    S(ret);
    cout << "done!\n";
}

Answer from a friend:

return value optimization (RVO). It is an optimization specifically blessed by the C++ specification. While the compiler is creating the returnLocalVar function, it is allowed for it to create the CAT temporary in main’s stack space instead of returnLocalVar’s stack space. Then, instead of returning it by making a copy, it just leaves it there on the stack where main can find it. The compiler can’t always figure out whether that would be safe, so it only does it in predictable circumstances.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s