Title
Standard layout class with empty base class also in first member
Status
open
Section
11.2 [class.prop]
Submitter
Lénárd Szolnoki

Created on 2023-05-10.00:00:00 last changed 19 months ago

Messages

Date: 2024-03-06.20:13:27

Suggested resolution (reviewed by CWG 2024-03-01, with no consensus):

  1. Change in 11.2 [class.prop] bullet 3.7 as follows:

    • ...
    • has no element of the set M(S) of types as a base class, where for any type X, M(X) is defined as follows, where B(S) is a set of types consisting of S and each direct and indirect base class of S. [Footnote: ...] [Note 2: M(X) is the set of the types of all non-base-class subobjects that can be at a zero offset in X. —end note]
      • If X is a non-union class type with no non-static data members, the set M(X) is empty.
      • If X is a non-union class type with a non-static data member of type X0 that is either of zero size or is the first non-static data member of X (where said member may be an anonymous union), the set M(X) consists of X0 is the union of B(X0) and the elements of M(X0).
      • If X is a union type, the set M(X) is the union of all M(Ui) and the set containing all Ui B(Ui), where each Ui is the type of the ith non-static data member of X.
      • If X is an array type with element type Xe, the set M(X) consists of Xe is the union of B(Xe) and the elements of M(Xe).
      • If X is a non-class, non-array type, the set M(X) is empty.
  2. Add more examples in 11.2 [class.prop] paragraph 4:

    
      struct X {};                     // standard-layout class
      struct Y : X { char c; };        // standard-layout class
      struct Z : X { Y y; };           // not a standard-layout class
    
      struct H {};                     // standard-layout class
      struct I : H {};                 // standard-layout class
      struct J { I i; };               // standard-layout class
      struct K : I { J j; };           // not a standard-layout class
    
Date: 2024-03-06.20:13:27

(From submission #317.)

Consider:

  struct A {};
  struct B : A { char c; };

  struct C : A {
    B b;
  };

Class C satisfies all the conditions to be considered standard-layout, including 11.2 [class.prop] bullet 3.7:

  • M(C) is the union of {B} and M(B) per 11.2 [class.prop] bullet 3.7.2.
  • M(B) is the union of {char} and M(char) per 11.2 [class.prop] bullet 3.7.2.
  • M(char) is an empty set per 11.2 [class.prop] bullet 3.7.5.

Thus, M(C) is {char,B}, neither of which is a base class of C, and thus C is standard-layout, contrary to popular ABI rules that do not provide pointer interconvertibility between C::b and C.

History
Date User Action Args
2023-05-26 21:54:10adminsetmessages: + msg7295
2023-05-10 00:00:00admincreate