Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an Object and Scope

I was working on a fraction class as a CS assignment, and wrote the following code:

fraction fraction::add(fraction other) {
    fraction temp;

    /* manipulate temp */

    return temp;
}

This worked perfectly, creating a new fraction object and then returning it to the calling code.

The question is, why did this work? My fraction temp should go out of scope when the add method returns and thus be destroyed, but it is passed back out to the calling code without so much as an error.

Why does returning something with local scope cause it to continue to exist after it goes out of scope?

like image 239
mfabel Avatar asked Oct 22 '13 18:10

mfabel


2 Answers

You're returning the value of temp, not the temp object itself. The value gets copied and returned to the calling function, the fact that temp then gets destroyed is irrelevant, here.

It's like this:

int a;
{
    int b = 5;
    a = b;
}
std::cout << a << std::endl;

After the closing brace, b has gone out of scope, but a still contains the value 5, and is fine. Approximately the same thing is happening for your function call.

If you return a pointer to a local object, it's a very different story. Attempts to dereference that pointer will invoke undefined behavior, since you're trying to access an object which no longer exists. But when you're just using the returned value, it doesn't matter whether that object exists or not, because you just have your own copy of the value it used to contain, at that point. (Technically it's still returning by value, here, and the pointer in the calling function will just contain its own copy of the address at which the local object used to reside - you just can't do anything useful with it, because the lifetime of the object that used to reside at that address has ended.)

like image 58
Crowman Avatar answered Oct 18 '22 16:10

Crowman


It doesn't continue to exist. You are returning by value temp is copied (or moved in C++11) into whatever the return value of the function is assigned to, then temp goes out of scope and is destroyed.

Or, on most modern compilers where Return Value Optimization is implemented, temp will actually be the same as the object you're assigning the return value of the function to wich won't have gone out of scope yet.

Looking at a simple example

fraction value;
fraction other_value;
fraction returned = value.add(other_value);

When value.add(other_value) is called it constructs temp in the member function's scope, then once it reaches the line return temp;, temp is copied into returned which is in the callers scope. Now the return statement has completed, the function ends, temp goes out of scope and is destroyed.

In the case of RVO, temp and returned are actually the same object and no copy is performed at all.

like image 4
David Brown Avatar answered Oct 18 '22 15:10

David Brown