const vector<int>& getVec(const vector<int> &vec)
{
return vec;
}
My function is like this and, if I call getVec
with a temporary object, can the code be safe?
int main()
{
const vector<int> &v = getVec({1,2,3,4,5});
}
I am running this code in g++ and Visual Studio but I get two different results:
-
g++ tells me: the function’s vector is the same as v and they have the same value.
-
Visual Studio tells me: the function’s vector has the same address as v but v.size() is only 0, not 5
Is there a standard answer for this situation? Can a const
reference return value only refer to values that existed before the function body?
2
Answers
As already mentioned in the comments, it is undefined behavior. It can be seen from C++11 standard draft, section 12.2/5.
As we can see, Neither function argument reference nor return reference extend the lifetime of temporary
{1,2,3,4,5}
. So inmain()
you have undefined behavior, you might end up with dangling reference.The code as shown is well-formed and doesn’t have any undefined behavior. Only if you actually use
v
later, then there will be undefined behavior.When calling
getVec
aconst vector<int>
temporary object will be materialized and initialized with{1,2,3,4,5}
, so that the reference in the function parameter can bind to it.Temporary objects live (by default) until the end of the full-expression in which they are materialized (which here is the expression
getVec({1,2,3,4,5})
together with the initialization ofv
). Binding them to a reference for the first time may extend the lifetime (under certain additional conditions), but this specifically does not apply to references in function parameters and wouldn’t really help anyway, since the reference in the function parameter itself doesn’t have a longer lifetime.So the temporary object lives long enough for
v
to bind to it, but is then after the initialization ofv
immediately destroyed.Therefore
v
will be dangling after its initialization and actually using it will cause undefined behavior. But simply initializing it this way will not.