Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
languagelawyer opened this issue Feb 7, 2019 · 13 comments · Fixed by #3485
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.

Comments

@languagelawyer
Copy link
Contributor

languagelawyer commented Feb 7, 2019

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

@jwakely
Copy link
Member

jwakely commented Feb 7, 2019

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).

@languagelawyer
Copy link
Contributor Author

languagelawyer commented Feb 7, 2019

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?

@jwakely
Copy link
Member

jwakely commented Feb 7, 2019

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.

@languagelawyer
Copy link
Contributor Author

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

@jensmaurer
Copy link
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?

@jensmaurer jensmaurer added the decision-required A decision of the editorial group (or the Project Editor) is required. label Feb 10, 2019
@zygoloid
Copy link
Member

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

@zygoloid zygoloid added cwg Issue must be reviewed by CWG. and removed decision-required A decision of the editorial group (or the Project Editor) is required. labels Feb 10, 2019
@jensmaurer
Copy link
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.

@languagelawyer
Copy link
Contributor Author

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

@jensmaurer
Copy link
Member

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

@languagelawyer
Copy link
Contributor Author

@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.

@jensmaurer
Copy link
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].

@languagelawyer
Copy link
Contributor Author

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

@jwakely
Copy link
Member

jwakely commented Feb 11, 2019

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.

@jensmaurer jensmaurer 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? Sep 16, 2019
@jensmaurer jensmaurer added the not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking. label Sep 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.
Projects
None yet
4 participants