C++ Logo

std-discussion

Advanced search

A contradiction between [class.base.init#9] and [class.copy.ctor#14]

From: jim x <xmh970252187_at_[hidden]>
Date: Wed, 23 Sep 2020 16:52:44 +0800
Hi, everyone, wish you a nice day.

I have an issue about two rules in [class.base.init] and [class.copy.ctor],
respectively. They are:

[class.base.init#9] <https://eel.is/c++draft/class.base.init#9>
In a non-delegating constructor, if a given potentially constructed
subobject *is not designated by a mem-initializer-id* (including the case
where there is no mem->initializer-list because the constructor has no
ctor-initializer), then


[class.copy.ctor#14] <https://eel.is/c++draft/class.copy.ctor#14>
The implicitly-defined copy/move constructor for a non-union class X
performs a memberwise copy/move of its bases and members. [Note 7: Default
member initializers of non-static data members are ignored. See also the
example in [class.base.init]. — end note] The order of initialization is
the same as the order of initialization of bases and members in a *user-defined
constructor *(see [class.base.init]). Let x be either the parameter of the
constructor or, for the move constructor, an xvalue referring to the
parameter. Each base or non-static data member is copied/moved in the
manner appropriate to its type


Except for the tips mentioned in `Note`, there's no any wording in the
standard that says the `implicitly-defined copy/move constructor` can
suppress the rules in [class.base.init#9] to apply to it. Due
to `implicitly-defined copy/move constructor` has no ctor-initializer, it
should obey [class.base.init#9]. So, it appears to be vague.

So, Is it necessary to reword the rule in [class.copy.ctor#14]
<https://eel.is/c++draft/class.copy.ctor#14> to suppress the rule
[class.base.init#9] explicitly? Such as:

The implicitly-defined copy/move constructor for a non-union class X
performs a memberwise copy/move of its bases and members *as if it exists a
corresponding member-initializer for each potentially constructed subobject*.


After this modification, this rule "Virtual base class subobjects shall be
initialized only once by the implicitly-defined copy/move constructor"
will also be clear due to it will conform to this rule, namely "A
mem-initializer where the mem-initializer-id denotes a virtual base class
is ignored during execution of a constructor of any class that is not the
most derived class." in [class.base.init#7]
<https://eel.is/c++draft/class.base.init#7>
Although, there's a rule in the standard to suppress that the constructor
of non most derived class to initialize the virtual base subobject, that
is:
[class.base.init#13.1] <https://eel.is/c++draft/class.base.init#13.1>
First, and only for the constructor of the most derived class
([intro.object]), virtual base classes are initialized in the order they
appear on a depth-first left-to-right traversal of the directed acyclic
graph of base classes, where “left-to-right” is the order of appearance of
the base classes in the derived class base-specifier-list.

However, it's a bit obscure, not obvious. Well, this modification is not
completely for why the virtual base subobject only initialized once, but
explicitly reject the rule in [class.base.init#9]
<https://eel.is/c++draft/class.base.init#9> which may apply
to `implicitly-defined copy/move constructor`. BTW, the sentence "The order
of initialization is the same as the order of initialization of bases and
members in a *user-defined constructor *(see [class.base.init])." sounds
like that these rules in [class.base.init] is applied to `user-defined
constructor`.

Anyhow, It's only my reading. If you have any other opinions, please tell
me, thanks.

Received on 2020-09-23 03:52:58