You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[intro.execution] CWG2431: Destruction of a temp. object bound to a reference is not a full-expression?ย #2664
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
voidfoo()
{
constauto& 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
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).
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.
@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.
@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.
@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].
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.
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
Activity
jwakely commentedon Feb 7, 2019
If you have multiple lifetime-extended temporaries, do their destructors produce multiple full-expressions?
The current wording seems to allow the destructor invocations
rk.~Klass()andrk2.~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 commentedon Feb 7, 2019
If I have multiple non-reference variables, do their destruction produce multiple full-expressions?
jwakely commentedon 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 commentedon Feb 7, 2019
Ok, the difference could be intended, lets wait what others will say.
jensmaurer commentedon Feb 10, 2019
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?
zygoloid commentedon Feb 10, 2019
Given the ambiguity Jonathan mentioned, I think we should process this as a core issue.
jensmaurer commentedon Feb 11, 2019
@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 commentedon Feb 11, 2019
@jensmaurer the difference would be observable if a destructor throws an exception.
jensmaurer commentedon Feb 11, 2019
@languagelawyer, sorry, maybe it's too early in the morning for me, but could you please be more specific?
languagelawyer commentedon Feb 11, 2019
@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 commentedon Feb 11, 2019
@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 commentedon Feb 11, 2019
@jensmaurer hm, indeed. Then I also don't see a difference.
jwakely commentedon 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.
[-][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?[/+]