Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning const reference

Tags:

c++

I'm somewhat confused about the declaration of functions returning const references to temporaries.

In the following code

#include <string>
#include <iostream>

using namespace std;

const string& foo() { 
    return string("foo"); 
}
string bar() { 
    return string("bar"); 
}

int main() {
    const string& f = foo();
    const string& b = bar();
    cout << b;

}

What is the difference between methods foo and bar ?

Why does foo give me warning: returning reference to local temporary object [-Wreturn-stack-address]. Isn't a copy of the temporary created on const string& f = foo(); ?

like image 309
perencia Avatar asked Apr 17 '16 06:04

perencia


3 Answers

string("foo") creates an object of type std::string containing the value "foo" locally in the function. This object will be destroyed at the end of the function. So returning the reference to that object will be invalid once the code leaves that function [1]. So in main, you will never have a valid reference to that string. The same would be true if you created a local variable inside foo.

The WHOLE point of returning a reference is that you don't make a copy, and initializing a reference (string &f = foo() is an initialization) will not create a copy of the original object - just another reference to the same object [which is already invalid by the time the code is back in main]. For many things, references can be seen as "a different name for the same thing".

The lifetime of the referred object (in other words, the actual object the "alias name" refers to) should ALWAYS have a lifetime longer than the reference variable (f in this case).

In the case of bar, the code will make a copy as part of the return string("bar");, since you are returning that object without taking its reference - in other words, by copying the object, so that works.

[1] pedantically, while still inside the function, but after the end of the code you have written within the function, in the bit of code the compiler introduced to deal with the destruction of objects created in the function.

like image 58
Mats Petersson Avatar answered Oct 10 '22 17:10

Mats Petersson


Isn't a copy of the temporary created on const string& f = foo();

Where did you hear that?

Adding const to a reference often allows the lifetime of a temporary with which it's been initialised to be extended to the lifetime of the reference itself. There's never a copy.

Even that's not the case here, though. The object you're binding to the reference goes out of scope at the end of the function and that takes precedence over everything else.

You're returning a dangling reference; period.

like image 28
Lightness Races in Orbit Avatar answered Oct 10 '22 18:10

Lightness Races in Orbit


Why does foo give me warning: returning reference to local temporary object [-Wreturn-stack-address].

You are creating a temporary string object inside foo(), and you are returning a reference to that object which will immediately go out of scope (dangling reference).

const string& foo() { 
    return string("foo"); // returns constant reference to temporary object
}                         // object goes out of scope

bar() is quite different:

string bar() {            
    return string("bar"); // returns a copy of temporary string
}
...
const string& b = bar();  // reference an rvalue string

What is the difference between methods foo and bar ?

foo() returns a constant (dangling) reference while bar() returns a copy of a temporary string object.

like image 37
Andreas DM Avatar answered Oct 10 '22 17:10

Andreas DM