Skip to content

[intro.execution] CWG2431: Destruction of a temp. object bound to a reference is not a full-expression? #2664

Description

@languagelawyer

http://eel.is/c++draft/intro.execution#def:full-expression:

A full-expression is
— an invocation of a destructor generated at the end of the lifetime of an object other than a temporary object ([class.temporary]), or

Here is an example

void foo()
{
    const auto& rk = Klass{};
    Klass k;
    // ...
    // generated invocation `k.~Klass()` is a full-expression
    // generated invocation `rk.~Klass()` is not a full-expression?
}

I think it is intended to be a full-expression, so the Standard should say something like

other than a temporary object whose lifetime was not extended

Activity

  1. jwakely commented on Feb 7, 2019

    @jwakely
    Member

    If you have multiple lifetime-extended temporaries, do their destructors produce multiple full-expressions?

    {
        const auto& rk = Klass{};
        const auto& rk2 = Klass{};
        // ...
    }
    

    The current wording seems to allow the destructor invocations rk.~Klass() and rk2.~Klass() to be part of the same full-expression (though it could be clearer whether that is intended, or whether your reading is correct).

  2. languagelawyer commented on Feb 7, 2019

    @languagelawyer
    ContributorAuthor

    If you have multiple lifetime-extended temporaries, do their destructors produce multiple full-expressions?

    If I have multiple non-reference variables, do their destruction produce multiple full-expressions?

  3. jwakely commented on Feb 7, 2019

    @jwakely
    Member

    Yes, but the destruction of temporary objects doesn't have to produce multiple full-expressions, so there's no inherent requirement that destruction of objects happens in separate full-expressions.

  4. languagelawyer commented on Feb 7, 2019

    @languagelawyer
    ContributorAuthor

    Ok, the difference could be intended, lets wait what others will say.

  5. jensmaurer commented on Feb 10, 2019

    @jensmaurer
    Member

    The text is clearly wrong (a lifetime-extended temporaries should be treated as-if it were a non-reference variable), but is the fix editorial?

  6. added
    decision-requiredA decision of the editorial group (or the Project Editor) is required.
    on Feb 10, 2019
  7. zygoloid commented on Feb 10, 2019

    @zygoloid
    Member

    Given the ambiguity Jonathan mentioned, I think we should process this as a core issue.

  8. added
    cwgIssue must be reviewed by CWG.
    and removed
    decision-requiredA decision of the editorial group (or the Project Editor) is required.
    on Feb 10, 2019
  9. jensmaurer commented on Feb 11, 2019

    @jensmaurer
    Member

    @zygoloid, @jwakely: What would the effective difference be between "one full-expression for destruction of several lifetime-extended temporaries" vs. "one full-expression each"? We can't have temporaries in default arguments for destructors.

  10. languagelawyer commented on Feb 11, 2019

    @languagelawyer
    ContributorAuthor

    @jensmaurer the difference would be observable if a destructor throws an exception.

  11. jensmaurer commented on Feb 11, 2019

    @jensmaurer
    Member

    @languagelawyer, sorry, maybe it's too early in the morning for me, but could you please be more specific?

  12. languagelawyer commented on Feb 11, 2019

    @languagelawyer
    ContributorAuthor

    @jensmaurer if there are several temporary object destructor invocations in one full-expression and one of them throws an exception, it will finish evaluating the rest of the full-expression and could left some destructors not invoced. But if each destructor invocation is a full-expression and one of them thows, the following destructors still would be called during stack unwinding.

  13. jensmaurer commented on Feb 11, 2019

    @jensmaurer
    Member

    @languagelawyer: Such behavior would be at odds with [stmt.jump] p2: Even if a destructor throws an exception, you still need to execute the rest of the destructors, now in the context of stack unwinding [except.ctor].

  14. languagelawyer commented on Feb 11, 2019

    @languagelawyer
    ContributorAuthor

    @jensmaurer hm, indeed. Then I also don't see a difference.

  15. jwakely commented on Feb 11, 2019

    @jwakely
    Member

    I'm not aware of any way the difference is observable, so maybe it can be changed editorially (or maybe it doesn't need to change at all). My original comment was just to say that "it is intended to be a full-expression" may need additional justification, as it's not obvious to me whether that really is the intention.

  16. changed the title [-][intro.execution] Destruction of a temp. object bound to a reference is not a full-expression?[/-] [+][intro.execution] CWG2431: Destruction of a temp. object bound to a reference is not a full-expression?[/+] on Sep 16, 2019
  17. added
    not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.
    on Sep 16, 2019
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

    cwgIssue must be reviewed by CWG.not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions