C++ Logo


Advanced search

Re: Accessing data members in constructors' function try bocks

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Wed, 18 Jan 2023 17:38:30 +0000
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.

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.

Received on 2023-01-18 17:38:43