6

A standard-layout class is defined in [class]/7 in C++14, as follows (emphasis is mine):

A standard-layout class is a class that:

  • (7.1) — has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • (7.2) — has no virtual functions (10.3) and no virtual base classes (10.1),
  • (7.3) — has the same access control (Clause 11) for all non-static data members,
  • (7.4) — has no non-standard-layout base classes,
  • (7.5) — either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • (7.6) — has no base classes of the same type as the first non-static data member.

My concern is in relation to bullet (7.5): how is it possible to have no non-static data members in the most derived class and at the same time having one base class with non-static data members?

In other words, aren't the non-static data members of the base class, also non-static data members of the most-derived class?

Alexander
  • 2,581
  • 11
  • 17

1 Answers1

9

Yes, this is a defect in C++14, specifically CWG 1813. Although it can be repaired by reading "non-static data members" to refer only to direct (non-inherited) non-static data members (as is probably necessary elsewhere), the chosen fix has been to replace the language you found problematic with the following:

A standard-layout class is a class that: [...]

  • has all non-static data members and bit-fields in the class and its base classes first declared in the same class, [...]

This is a little tricky to get right; there is some resistance to the idea of considering inherited members as members of the derived class, even though [class.derived] has:

[...] Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class. Members of a base class other than constructors are said to be inherited by the derived class. [...]

Notwithstanding this, a number of places where both direct and inherited non-static data members are intended to be considered specifically call out inherited data members, for example also in [class] (after the resolution to CWG 1672):

8.6 - an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union),

Or in [basic.lval]:

7.8 - If X is a non-union class type, the set M(X) is empty if X has no (possibly inherited (Clause 10)) non-static data members; [...]

Meanwhile, in many places "members" has to be read as referring only to direct members to make sense; to begin with and only looking at non-static data members (not member functions), [expr.rel]/3.2, [expr.const]/5.1, [dcl.constexpr]/4.6, [class.mem]/17, /19, [special]/5, [class.ctor]/4.3, /4.4, /4.10, /4.12, [class.dtor]/5.6, [class.base.init]/2, /13.3, [class.copy]/12.2, /12.4, /18.2, /25.2, /25.4, /26.3, /27, [except.spec]/15.1.1.1, /15.2, /15.3 are all places where "non-static data members" could or should have "direct" prefixed.

On the other hand, in some places (e.g. in the amended [class], or in [class.copy]/23.2-23.3, /28) "members" is implicitly taken to include inherited members, so it's a bit of a mess.

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • `No, non-static data members of a base class are not considered to be non-static data members of the derived class.` Is there a specific quote for this in the Standard? – Alexander Oct 06 '16 at 19:39
  • `7.8 - If X is a non-union class type, the set M(X) is empty if X has no (possibly inherited (Clause 10)) non-static data members;` I couldn't find this in C++14. – Alexander Oct 06 '16 at 19:42
  • @Alexander that's [CWG 1672](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1672). – ecatmur Oct 06 '16 at 19:48
  • I'm looking forward to your post in c++ std-discussion. Thanks. – Alexander Oct 06 '16 at 20:41
  • 1
    @Alexander I've done my best: https://groups.google.com/a/isocpp.org/d/msg/std-discussion/PM4TMJzD0tM/y5JJWG6_CAAJ – ecatmur Oct 06 '16 at 22:04
  • Congrats. That was a great answer (+1) – Belloc Oct 07 '16 at 13:22