Skip to content

CWG3063 [class.temporary] Lifetime extension of temporaries to opaque lifetimes past function return #760

Closed
cplusplus/draft
#8492

Description

@hubert-reinterpretcast

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): [class.temporary]

Link to reflector thread (if any): N/A

Issue description:

P2748R5, "Disallow Binding a Returned Glvalue to a Temporary" only adds an error for functions that return references but entirely strikes the provision that prevents lifetime-extension of temporaries bound to the return value of a function. It thus creates situations whereby temporaries created within a function can be lifetime-extended to lifetimes that are opaque to the function.

Consider:

struct B { ~B(); };
struct A { const B &b; };
A foo() { return {{}}; }
void bar();
int main() {
  A a = foo();
  bar();
}

Based on guaranteed copy elision, the reference that the B temporary is bound to is the a.b from main. [class.temporary] says that the lifetime of the B temporary is extended. This requirement is not practical to implement.

Suggested resolution:

Restore [class.temporary] bullet 6.11 from C++23.

  • The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

Activity

  1. jensmaurer commented on Sep 12, 2025

    @jensmaurer
    Member

    CWG3063

    Note the added emphasis on reference members.

  2. changed the title [-][class.temporary] Lifetime extension of temporaries to opaque lifetimes past function return[/-] [+]CWG3063 [class.temporary] Lifetime extension of temporaries to opaque lifetimes past function return[/+] on Sep 12, 2025
  3. hubert-reinterpretcast commented on Sep 12, 2025

    @hubert-reinterpretcast
    MemberAuthor

    Note the added emphasis on reference members.

    Got it. Thanks Jens!

  4. t3nsor commented on Sep 12, 2025

    @t3nsor

    I think, if I had remembered this lifetime extension case during drafting, I would have advocated that it also be banned in a return statement based on the same rationale: it immediately dangles. That is to say, [stmt.return]/6 could say something like

    [...] a return statement that binds

    • the returned reference , or
    • a constituent reference ([expr.const]) of the returned object

    to a temporary expression ([class.temporary]) is ill-formed.

    with an additional example as well.

    If we go with the current proposed resolution, maybe it should also be updated to use "constituent reference". The problem is that it should apply not only to reference members but also reference members of subobjects.

  5. hubert-reinterpretcast commented on Sep 12, 2025

    @hubert-reinterpretcast
    MemberAuthor

    maybe it should also be updated to use "constituent reference"

    We may want to move "constituent reference" out of [expr.const] though.

  6. jensmaurer commented on Sep 14, 2025

    @jensmaurer
    Member

    I've updated CWG3063 accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions