Matt
Matt

Reputation: 161

C++ - Return by value behavior

I'm trying to learn how copies work when a function returns by value. I'm confused by the following piece of code:

#include <iostream>
using namespace std;

class X {
    public:
        virtual ~X() { cout << "~X() " ; }
        X() { cout << "X() "; }
        X(X const& other) {
            cout << "X(X const&) ";
        }
};

X f(X x) {
    cout << "# ";
    return x;
}

X g(X x) {
    X y = x;
    cout << "# ";
    return y;
}

int main() {
    X a;
    cout << endl << "f: ";
    a = f(a);
    cout << endl << "g: ";
    a = g(a);
    cout << endl;       
}

The output is:

X()
f: X(X const&) # X(X const&) ~X() ~X()
g: X(X const&) X(X const&) # ~X() ~X()
~X()

This suggests, that f does a copy of x before returning, but g doesn't. How is this possible, does x not act as a normal variable in the scope of f because it is one of its arguments? What is the general rule for this type of behavior?

Upvotes: 0

Views: 70

Answers (1)

User 10482
User 10482

Reputation: 1012

Here's the optimization that I believe is taking place for g() but not for f().

Non-mandatory elision of copy/move (since C++11) operations:

In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type. This variant of copy elision is known as NRVO, "named return value optimization".

(excerpt from cppreference. The bold text is done by me to mark important parts regarding the question)

It's non-mandatory, so might change with compiler/optimizations included.

Upvotes: 4

Related Questions