Reputation: 103
Why does this code work? It prints out 60
every single time. First of all, const thingy&
indicates that the function returns a reference to an already existing variable, not a nameless construction. Secondly, shouldn't that temporary die when the function returns, thus creating a null reference? I am using whatever the latest GCC version is on OSX... Can somebody please explain to me why this works?
#include <iostream>
using namespace std;
struct thingy {
double things;
double moreThings;
double evenMoreThings;
};
const thingy& getThingy() {
return {60, 60, 60};
}
int main() {
cout << getThingy().evenMoreThings << endl;
}
And if that works, then why doesn't this?
const thingy& getThingy() {
thingy t{60, 60, 60};
return t;
}
Upvotes: 0
Views: 348
Reputation: 66
We should not mix rvalue and lvalue references. The best option is to return by copy..
Returning lavalue rerense of local variable will always lead to problems.
Upvotes: -1
Reputation: 1868
Neither of your two options are required to work by the C++ standards, and so it shouldn't be assumed that either will necessarily work under any particular circumstances.
Compiler specifics have caused the first option to work where you return the value directly.
Ideally, you would return by value (thingy getThingy();
) instead to ensure compatibility. Any compiler worth your time will still apply return value optimisation to this, preventing the need for a copy constructor call and still allowing the necessary efficiency.
Upvotes: 2
Reputation: 196
The compiler is performing the Return Value Optimization here.
https://en.wikipedia.org/wiki/Return_value_optimization
The compiler is able to take the value constructed at the return and won't even need to copy it. However, in the example where you construct the struct inside the function, it really is a local variable, and thus falls out of scope at the end of the function, invalidating the reference.
Upvotes: 1