Ord
Ord

Reputation: 5843

C++ what happens first - destruction of function's parameters or handling of function's return values?

I have the following code:

class thing {
    public:
        thing(const thing& x) { cout << "copy" << endl; }
        thing() { cout << "create" << endl; }
        ~thing() { cout << "destroy" << endl; }

        thing& operator=(const int& rhs) { cout << "assign" << endl; }
};

int foo(thing x) {
    return 5;
}

int main() {
    thing bar;
    thing newThing;
    newThing = foo(bar);

    getchar();
}

When I run this, at the point where my program reaches the getchar(), I expect to see the following output:

create // since bar is default constructed
create // since newThing is default constructed
copy // since bar gets passed by value into foo
destroy // since foo's local thing `x` is destructed when foo ends
assign // since the 5 returned by foo is assigned to newThing

Instead, I get this:

create
create
copy
assign
destroy

Note that assign and destroy have swapped from what I expected.

What's up with this? Why does the assignment appear to happen before the local x is destructed? Note that if I declare a local thing in the body of foo, it gets destructed before the assignment happens, as I would expect.

Upvotes: 2

Views: 221

Answers (2)

user207421
user207421

Reputation: 311018

Parameters are constructed and destructed by the caller, not by the method. 'foo()'s local thing' isn't foo()'s at all, it is the caller's: the caller destroys it.

Upvotes: 1

Daniel Frey
Daniel Frey

Reputation: 56903

With this signature:

int foo(thing x) {
    return 5;
}

You are creating a function where the instance of thing is a parameter. Parameters are passed in by the caller of the method, that mean that the expression here:

newThing = foo(bar);

creates a temporary object of thing which is copied from bar. Those temporaries have a lifetime upto the end of the full expression, therefore the destructor of this temporary is called after the assignment happened.

Why is that so? Because the compiler only generates one function called foo and this function can not construct x locally - it would not know with which parameters to construct it. There could be multiple constructors which could be valid and several different sets of parameters. The compiler therefore must construct the temporary on the caller's side of the call.

Upvotes: 5

Related Questions