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();
?
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.
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.
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.
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