Date: Thu, 19 Jan 2023 08:29:33 -0500
On Thu, Jan 19, 2023 at 4:29 AM Frank B. Brokken via Std-Discussion
<std-discussion_at_[hidden]> wrote:
> It's obvious that class type data members cannot be used in
> constructor function-try-block handlers, as their destructors have
> already been called by the time execution enters those handlers, but
> as basic-type data members don't have destructors they remain
> available for as long as the object's memory remains available (or
> am I missing something and are there some spooky things going on by
> the time the handlers begin their executions?).
All objects have lifetimes and are bound by [basic.life], so even
scalar subobjects will be destroyed before the handler is entered.
This is made explicit by 14.3 [except.ctor] para. 3:
If the initialization of an object other than by delegating
constructor is terminated by an exception, the destructor is invoked
for each of the object's subobjects that were known to be
initialized by the object's initialization and whose initialization
has completed (9.4). [...] The subobjects are destroyed in the
reverse order of the completion of their construction. Such
destruction is sequenced before entering a handler of the
function-try-block of the constructor or destructor, if any.
as well as 6.7.3 [basic.life] para. 1:
The lifetime of an object o of type T ends when:
- if T is a non-class type, the object is destroyed, or
- if T is a class type, the destructor call starts, or [...]
alongside 6.7.3 [basic.life] para. 7:
[...] after the lifetime of an object has ended and before the
storage which the object occupied is reused or released, [...] The
program has undefined behavior if:
- the glvalue is used to access the object, or [...]
However, the wording for this clause, as well as 11.4.7 [class.cdtor]
para. 13 which specifies the order of destruction of subobjects after
an ordinary destructor returns, is somewhat sloppy. In particular,
subobjects of non-class type do not have any destructor to invoke, but
instead a pseudo-destructor which destroys them when called (7.6.1.3
[expr.call] para. 5). But I still believe it is the intent that all
subobjects are destroyed one way or another; otherwise, it would have
been explicitly written that "the destructor is invoked for each of
the object's *non-class* subobjects", or something to that effect.
<std-discussion_at_[hidden]> wrote:
> It's obvious that class type data members cannot be used in
> constructor function-try-block handlers, as their destructors have
> already been called by the time execution enters those handlers, but
> as basic-type data members don't have destructors they remain
> available for as long as the object's memory remains available (or
> am I missing something and are there some spooky things going on by
> the time the handlers begin their executions?).
All objects have lifetimes and are bound by [basic.life], so even
scalar subobjects will be destroyed before the handler is entered.
This is made explicit by 14.3 [except.ctor] para. 3:
If the initialization of an object other than by delegating
constructor is terminated by an exception, the destructor is invoked
for each of the object's subobjects that were known to be
initialized by the object's initialization and whose initialization
has completed (9.4). [...] The subobjects are destroyed in the
reverse order of the completion of their construction. Such
destruction is sequenced before entering a handler of the
function-try-block of the constructor or destructor, if any.
as well as 6.7.3 [basic.life] para. 1:
The lifetime of an object o of type T ends when:
- if T is a non-class type, the object is destroyed, or
- if T is a class type, the destructor call starts, or [...]
alongside 6.7.3 [basic.life] para. 7:
[...] after the lifetime of an object has ended and before the
storage which the object occupied is reused or released, [...] The
program has undefined behavior if:
- the glvalue is used to access the object, or [...]
However, the wording for this clause, as well as 11.4.7 [class.cdtor]
para. 13 which specifies the order of destruction of subobjects after
an ordinary destructor returns, is somewhat sloppy. In particular,
subobjects of non-class type do not have any destructor to invoke, but
instead a pseudo-destructor which destroys them when called (7.6.1.3
[expr.call] para. 5). But I still believe it is the intent that all
subobjects are destroyed one way or another; otherwise, it would have
been explicitly written that "the destructor is invoked for each of
the object's *non-class* subobjects", or something to that effect.
Received on 2023-01-19 13:29:45