c++referencecompiler-warningstemporary-objects

Why does "return string(...)" return a reference to a temporary?


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


Solution

  • 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.