<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 650</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="650"></A><H4>650.
  
Order of destruction for temporaries bound to the returned value of a function
</H4>
<B>Section: </B>6.8.7&#160; [<A href="https://wg21.link/class.temporary">class.temporary</A>]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Aug 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>In describing the order of destruction of temporaries,
6.8.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>] paragraphs 4-5 say,</P>

<BLOCKQUOTE>

<P>There are two contexts in which temporaries are destroyed at a
different point than the end of the full-expression...</P>

<P>The second context is when a reference is bound to a
temporary...  A temporary bound to the returned value in a function
return statement (8.8.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>]) persists until the
function exits.</P>

</BLOCKQUOTE>

<P>The following example illustrates the issues here:</P>

<PRE>
    struct S {
        ~S();
    };

    S&amp; f() {
        S s;            // #1
        return
            (S(),       // #2
             S());      // #3
    }
</PRE>

<P>If the return type of <TT>f()</TT> were simply <TT>S</TT> instead
of <TT>S&amp;</TT>, the two temporaries would be destroyed at the end
of the full-expression in the <TT>return</TT> statement in reverse
order of their construction, followed by the destruction of the
variable <TT>s</TT> at block-exit, i.e., the order of destruction
of the <TT>S</TT> objects would be #3, #2, #1.</P>

<P>Because the temporary #3 is bound to the returned value, however,
its lifetime is extended beyond the end of the full-expression, so
that <TT>S</TT> object #2 is destroyed before #3.</P>

<P>There are two problems here.  First, it is not clear what
&#8220;until the function exits&#8221; means.  Does it mean that
the temporary is destroyed as part of the normal block-exit
destructions, as described in 8.8 [<A href="https://wg21.link/stmt.jump#2">stmt.jump</A>] paragraph 2:</P>

<BLOCKQUOTE>

On exit from a scope (however accomplished), destructors (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]) are called for all constructed objects with automatic
storage duration (6.8.6.4 [<A href="https://wg21.link/basic.stc.auto">basic.stc.auto</A>]) (named objects or
temporaries) that are declared in that scope, in the reverse order of
their declaration.

</BLOCKQUOTE>

<P>Or is the point of destruction for #3
<I>after</I> the destruction of the &#8220;constructed objects...
that are <I>declared</I> [emphasis mine] in that scope&#8221;
(because temporary #3 was not &#8220;declared&#8221;)?  I.e.,
should #3 be destroyed before or after #1?</P>

<P>The other problem is that, according to the recollection of one
of the participants responsible for this wording, the intent was not
to extend the lifetime of #3 but simply to emphasize that its
lifetime ended before the function returned, i.e., that the result of
<TT>f()</TT> could not be used without causing undefined behavior.
This is also consistent with the treatment of this example by many
implementations; MSVC++, g++, and EDG all destroy #3 before #2.</P>

<P><U>Suggested resolution:</U></P>

<P>Change 6.8.7 [<A href="https://wg21.link/class.temporary#5">class.temporary</A>] paragraph 5 as indicated:</P>

<BLOCKQUOTE>

<DEL>A</DEL> <INS>The lifetime of a</INS> temporary bound to the returned
value in a function return statement (8.8.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>])
<DEL>persists until the function exits</DEL> <INS>is not extended; it is
destroyed at the end of the full-expression in the return statement</INS>.

</BLOCKQUOTE>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 6.8.7 [<A href="https://wg21.link/class.temporary#5">class.temporary</A>] paragraph 5 as follows (converting
the running text into a bulleted list and making the indicated edits
to the wording):</P>

<BLOCKQUOTE>

... The temporary to which the reference is bound or the temporary
that is the complete object of a subobject to which the reference is
bound persists for the lifetime of the reference except<INS>:</INS> <DEL>as
specified below.</DEL>

<UL>
<LI><P>A temporary bound to a reference member in a constructor's
ctor-initializer (11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>]) persists until the
constructor exits.</P></LI>

<LI><P>A temporary bound to a reference parameter in a function call
(7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]) persists until the completion of the full
expression containing the call.</P></LI>

<LI><P>
<DEL>A</DEL> <INS>The lifetime of a</INS> temporary bound to the
returned value in a function return statement (8.8.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>]) <DEL>persists until the function exits</DEL> <INS>is not extended; the
temporary is destroyed at the end of the full-expression in the return
statement.</INS>
</P></LI>

</UL>

<P>The destruction of a temporary whose lifetime is not extended...</P>

</BLOCKQUOTE>

<BR><BR>
</BODY>
</HTML>
