Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return const reference vs temporary object

I'm wondering why returning const reference of a local object is illegal whereas returning a local object is legal as long as you assign it to a const reference?

vector<int> f_legal() {
    vector<int> tempVec;
    tempVec.push_back(1);
    return tempVec;
}

const vector<int>& f_illegal() {
    vector<int> tempVec;
    tempVec.push_back(1);
    return tempVec;
}

void g() {
    const vector<int>& v1 = f_legal(); // legal
    const vector<int>& v2 = f_illegal(); // illegal
}

Edit: My point is that if assigning a const ref to a returned local variable is legal, then shouldn't assigning a const ref to a returned const ref of a local variable be legal as well?

like image 213
Monster Hunter Avatar asked Feb 12 '16 16:02

Monster Hunter


People also ask

Is temporary object created in return by reference?

Explanation: The temporary object is not created. If object is returned by reference, a particular memory location will be denoted with another name and hence same address values will be used. 10.

Can a const function return a reference?

If the thing you are returning by reference is logically part of your this object, independent of whether it is physically embedded within your this object, then a const method needs to return by const reference or by value, but not by non-const reference.

Does const reference extend lifetime?

In the by-reference case, we get a const Base& reference that refers to a Derived object. The entire temporary object, of type Derived , is lifetime-extended.

Does const reference make a copy?

Not just a copy; it is also a const copy. So you cannot modify it, invoke any non-const members from it, or pass it as a non-const parameter to any function.


2 Answers

Even if you assign it to a const reference, the return value is declared as passed by value, that means it'll be copied[1] to outside as a temporary object, and then binded to the const reference. Binding temporary object to a const reference is fine, the object won't be destroyed until getting out of the lifetime of the const reference.

On the other hand, returning reference of a local variable is illegel. The local variable'll be destroyed when the function returned, that means the outside reference will be dangled.

EDIT

My point is that if assigning a const ref to a returned local variable is legal, then shouldn't assigning a const ref to a returned const ref of a local variable be legal as well?

The point is the 1st case is not assigning a const ref to a returned local variable, it's assigning a const ref to a returned temporary variable. (Which might copied from the local variable.)


[1] The copy might be omitted according to RVO technically.

like image 76
songyuanyao Avatar answered Sep 21 '22 18:09

songyuanyao


Returning a reference to a local variable is illegal (Undefined Behavior). Period. There is no const or mutable clause.

This is because local function variables have automatic storage duration. They are "destroyed" after the function exits. If the function returns a reference to such a variable, that reference it is said to be dangling: it refers to an object that no longer exists.

The first one is legal because of a special C++ rule: initializing a reference to a prvalue extends the lifetime of that temporary object to the lifetime of the reference.

like image 39
bolov Avatar answered Sep 18 '22 18:09

bolov