2 ms·
If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that
by Jare 10y ago
If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that's UB. Essentially,
int const &r = f(3);
and
int r = f(3);
would both be UB under that implementation-defined case.
The posted article, second row of "common mistakes", describes returning a const reference parameter, when called with a prvalue, as blanket UB.
Finally someone clarified: https://timsong-cpp.github.io/cppwp/class.temporary#6.1 https://timsong-cpp.github.io/cppwp/class.temporary#6.1
"6.1 A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call."
So, while the parameter's (the reference "int const &a") lifetime is implementation-defined, the temporary to which that parameter refers to is the full expression of the call. Sanity is restored.
- fauigerzigerk 10y agoYou're right, good point.
- Jeaye 10y agoThanks for digging into this. I'll update that example to be more clear about keeping an lvalue reference to the return value.
- MaulingMonkey 10y agoJust to help bring things home: const int& f(int parameter) { return parameter; } const int i = f(42); Is strictly undefined behavior under the simpler C++03 rules/wording of 5.2.2/4: "The lifetime of a parameter ends when the function in which it is defined returns.") P0135R0 would loosen the requirements on parameter's lifetime as a means of enabling guaranteed copy elision, in such a way that an implementation could technically decide to make this to have defined behavior (not that I suggest relying on it!)