C++ Logo


Advanced search

Re: Accessing data members in constructors' function try bocks

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Fri, 20 Jan 2023 00:31:36 +0000
On Wed, 18 Jan 2023 at 18:53, Brian Bi <bbi5291_at_[hidden]> wrote:

> On Wed, Jan 18, 2023 at 12:38 PM Edward Catmur via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>> On Wed, 18 Jan 2023 at 17:18, Frank B. Brokken via Std-Discussion <
>> std-discussion_at_[hidden]> wrote:
>>> Dear Edward Catmur, you wrote:
>>> > On Wed, 18 Jan 2023 at 16:02, Frank B. Brokken via Std-Discussion <
>>> > > ... reaches the constructor's function-try-block handler.
>>> >
>>> > This seems to me a simple corollary of [class.cdtor], particularly
>>> > paragraph 1. I'd even question whether normative wording is necessary
>>> under
>>> > [except.handle]; this could probably be a note.
>>> Hi Edward,
>>> Thanks for the fast reply to my question.
>>> 11.9.5 [class.cdtor] states:
>>> ... For an object with a non-trivial destructor, referring to any
>>> non-static member or base class of the object after the destructor
>>> finishes execution results in undefined behavior.
>>> However, that's not the situation I'm encountering. In the example an
>>> exception is thrown from the constructor's body and so no destructor is
>>> called.
>> Ah, true; the destructor of the class is only called in case of a
>> delegating constructor [except.ctor].
>> So either the class is not "under construction or destruction" and
>> [basic.life]p6 applies (and is thus inconsistent with [except.ctor]), or
>> [class.cdtor] is incomplete, or possibly both. This might be a defect.
> First of all, I'm sorry I didn't notice your first reply to this thread
> before I wrote my reply.
> Anyway, after having looked at [basic.life]/6, I don't see what the issue
> is. I think that [basic.life]/6 does not give license to do all the things
> that aren't specifically forbidden therein. If the class has a non-trivial
> constructor, then the restrictions in [class.cdtor]/1 apply in addition to
> the ones in [basic.life]/6.

Ah, you're right - I think I'm confused by reading "For an object under
construction or destruction, see [class.cdtor]. Otherwise..." but having
wording in [class.cdtor] (specifically, paragraph 1 thereof) apply also for
objects not under construction or destruction. My apologies.

Also, "Indirection through such a pointer is permitted but the resulting
lvalue may only be used in limited ways, as described below." gives a false
impression of being exhaustive when in fact, as you say, the restrictions
of [class.cdtor]/1 apply as well.

So if a class has a virtual base, and thus a non-trivial constructor,
[class.cdtor]/1 says we cannot refer to its members before construction
begins, [basic.life]/6 notwithstanding; if it has a trivial destructor,
however, we can refer to (but not access) those members after destruction
finishes. If instead we end its lifetime through storage reuse (which could
overwrite the vtable pointer, to put it crudely), [basic.life]/4 means we
cannot refer to those members; [basic.life]/6 (etc.) does not apply once
storage is reused. I think we're good here.

Going back to [except.handle]/10, this appears to complement
[class.cdtor]/1, implying that within a constructor (or destructor)
function-try-block, the class is still under construction (or destruction).
Is it problematic that [class.cdtor] 5 and 6 (typeid and dynamic_cast)
would appear to be allowed in such function-try-blocks? I suppose it's OK.

>> But before the exception is thrown its d_value has received a value,
>>> which is then displayed in its function-try-block.
>> Well, yes, but you aren't allowed to access that value, both because that
>> int object is outside its lifetime, and also because you aren't allowed to
>> refer to the int object to access its value.
>> >
>>> > > But why would referring to members of basic data types like 'int' be
>>> > > undefined?
>>> >
>>> >
>>> > If the data member is a member of a virtual base class, the vtable
>>> > (speaking concretely) and the offsets it contains necessary to compute
>>> the
>>> > address of that member may no longer be valid.
>>> True, but that's also not the situation encountered in my example.
>> This is a justification for the general rule. The Standard has cases
>> where a rule is more general than absolutely necessary for the sake of
>> simplicity.
>> > There is an issue that [class.cdtor] is actually more restrictive here
>>> than
>>> > [basic.life], meaning that operations that are allowed on an object
>>> fully
>>> > outside its lifetime (principally, referring to a non-virtual base
>>> class)
>>> > can no longer be performed once it is under construction or
>>> destruction.
>>> But that, too, is not the situation in my Int class: there's no base
>>> class
>>> either. It's just the plain Int class having a single int data member.
>>> So I'm
>>> still struggling with the question why referring to its d_value data
>>> member
>>> in the constructor's function-try-block implies undefined behavior
>> Your d_value might be a member via a virtual base class of Int. It isn't,
>> but it might be.
>> > I'm not sure if we've got around to opening a CWG issue there.
>>> Well, maybe I posted my question to the wrong list, but since
>>> https://isocpp.org/about/contact specifies that questions about the
>>> standard
>>> should be posted to this list, and since my question is about an item in
>>> the
>>> C++ standard and not so much about C++ itself I posted the question
>>> here. I
>>> tried several compilers with my example, and so far all resulting
>>> programs
>>> show the line 'value = 5'.
>> Well, that doesn't matter that much; there's lots of UB that isn't
>> detected by any compiler. Although it does weigh towards suggesting that it
>> might be worth considering relaxing that UB.
>> But please advise if I should address the question
>>> to 'StackOverflow C++'
>> No, you're in the right place. You might get an answer on SO, but they do
>> have a tendency to see the Standard as not to be questioned. Here is a bit
>> more relaxed.
>> --
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
> --
> *Brian Bi*

Received on 2023-01-20 00:31:49