Consider the following code snippet:
<code class="c++">#include <stdio.h> struct P2d { double x, y; P2d(double x, double y) : x(x), y(y) {} ~P2d() { printf("Destructor called\n"); } }; P2d center() { return P2d(10, 10); } int main(int argc, const char *argv[]) { const double& x = center().x; printf("x = %.18g\n", x); return 0; }</code>
When compiled with GCC 5.2.0, the P2d temporary instance is destroyed before entering the printf call in main. Despite this, the value of x is preserved and printed correctly. In other words, instead of binding x directly to the P2d temporary's x member, a second temporary double is created to copy the member's value.
On the other hand, Clang extends the lifetime of the P2d temporary to the lifetime of the x reference, resulting in the destructor being called after the printf in main.
This raises the question: is this behavior a bug in GCC or allowed by the standard?
CWG 1651 addresses this issue:
The resolution of issues 616 and 1213, making the result of a member access or subscript expression applied to a prvalue an xvalue, means that binding a reference to such a subobject of a temporary does not extend the temporary's lifetime. [class.temporary] should be revised to ensure that it does.
Currently, [class.temporary]/5 states: "The second context is when a reference is bound to a temporary." This has been interpreted to apply only to references that bind directly to temporary objects. Therefore, in the code snippet above, center().x is treated as a prvalue (by both Clang and GCC), and [class.temporary]/5 is not applicable.
However, GCC and Clang have not yet implemented the resolution of DR 1651, which is N3918. This resolution explicitly states that "member access and subscript expressions applied to a temporary expression yield temporary expressions," and adds that "the corresponding temporary object (if any) persists for the lifetime of the reference."
Thus, based on the wording of N3918, it appears that Clang is implementing the intended behavior, while GCC is not. DR 60297 notes that GCC does not extend lifetime for scalar subobjects of temporaries, as they are not covered by [dcl.init.ref]/(5.2.1.1).
In summary, the current behavior in GCC is correct according to the current wording of the standard, but the standard is likely to be revised to require lifetime extension in this case. Clang is already implementing the expected future behavior.
The above is the detailed content of ## Does Binding a Const Reference to a Temporary Object's Sub-part Extend its Lifetime?. For more information, please follow other related articles on the PHP Chinese website!