views:

99

answers:

4

A basic question that I'm not sure of the answer. Is the follow function valid?

std::vector<int> & test_function() {
   std::vector<int> x;

   // do whatever

   return x;
}

If so, why? Shouldn't the program delete x from the stack after the function returns? Thanks.

+7  A: 

The behavior is undefined. You shouldn't return references to local variables.

jMerliN
Damn, beat me to it!
Duracell
The code that's shown doesn't (by itself) contain any undefined behavior. The UB would happen in other code that calls this function.
Jerry Coffin
+6  A: 

The function is well-formed (syntactically correct), but as soon as the function returns, the returned reference is invalid and cannot be used.

To clarify: the code in question does not invoke any undefined behavior. You can safely call this function so long as you do not use the return value, e.g., this is valid:

test_function(); // ok

However, if you try to use the return value (i.e., initialize another reference with it or copy the referent into another object) then you will invoke undefined behavior because the lifetime of the referent (the object x) will have ended (x will be destroyed when the function returns because it is an automatic variable):

std::vector<int>& vec = test_function(); // undefined
std::vector<int> vec = test_function();  // undefined
James McNellis
On a serious note, if the structure being referenced is just a bunch of POD (no pointers) or is a primitive, if the normal stack frame is held, and you copy the value (not hold a reference to it, so your second example here), the original local value will be fine immediately following the return (`mov esp,ebp; pop ebp;` local stack frame is undisturbed). Destructors, however, are invoked and the data may be manipulated/changed. This is the wrong way to go about this, though, and predicting what will happen, even if guessed accurately in one place is not portable.
jMerliN
@jMerliN: Even for a POD type object, the results are formally undefined. The lifetime of a POD ends when its storage duration ends; for a local variable, this is at the point that the function returns. Using an object after its lifetime is ended results in undefined behavior. Does this possibly "work" in practice with POD type objects? Perhaps, but as you say, it is not behavior that should be relied upon.
James McNellis
It should definitely not be relied on when multi threading becomes standard as the location of the stack frame that was may have already been reused by another thread (Note the standard does not define how the stack or heap are implemented).
Martin York
A: 

You can't return a reference to a local variable for the same reason you can't return a pointer to a local variable, because on return from the function those local variables are deallocated and therefore the reference or pointer becomes invalid.

sashang
+2  A: 

Yes it's valid, but if you attempt to use the returned value, you'll get undefined behavior.

Jerry Coffin