In C++ is a return value guaranteed to be created before automatic variables in the function are destroyed? Notice Basket::get:
class Basket
{
public:
// Gift is a struct containing safely copyable things like int or string
Gift gift;
// Used to protect access and changes to gift
Mutex mutex;
// Copy gift into present, while locked to be thread safe
void put (const Gift & gift)
{
Lock lock(mutex); // Constructor locks, destructor unlocks mutex
this->gift = gift; // Gift assignment operator
}
// Return a memberwise-copy of gift, tries to be thread safe (but is it?)
Gift get ()
{
Lock lock(mutex); // Constructor locks, destructor unlocks mutex
return gift; // Gift copy constructor
}
};
I need Basket::get to perform its Gift copy constructor (of the temp object returned) prior to destruction of the lock object. Otherwise the gift object being returned can be corrupted by a simultaneous call to put.
My tests show the gift copy is indeed created before lock destruction, however, is it guaranteed? If not, I'll need to create a second temporary inside the function, such as:
Gift get ()
{
Gift result;
{
Lock lock(mutex);
result = gift;
}
return result;
}
Yes, the auto variable will remain in scope until after the return is finished. This is especially true if you are using a compiler that optimizes the return
, eg:
Gift get()
{
Lock lock(mutex);
return gift;
}
Gift g = basket.get();
Which would be equivilent to this sequence:
Gift g;
Lock lock(mutex);
g = Gift(gift);
lock.~Lock();
May be optimized to act more like this:
void get(Gift &ret)
{
Lock lock(mutex);
ret = gift;
}
Gift g;
basket.get(g);
Which would be equivilent to this sequence:
Gift g;
Lock lock(mutex);
g = gift;
lock.~Lock();
In other words, a temporary can be removed during the return
.
It's guaranteed. The return value is copied (if necessary) before the destruction occurs. Here's a similar question / answer that gives a good description of the sequence.
Scope and return values in C++
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