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?
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With