Layout compatibility with multiple empty bases
11.4 [class.mem]
Richard Smith

Created on 2013-04-27.00:00:00 last changed 49 months ago


Date: 2014-11-15.00:00:00

[Moved to DR at the November, 2014 meeting.]

Date: 2014-10-15.00:00:00

Proposed resolution (October, 2014):

Change Clause 11 [class] paragraph 7 as indicated and add the following as a new paragraph:

A class S is a standard-layout class is a class that if it:

  • ...

  • has no base classes of the same type as the first non-static data member element of the set M(S) of types (defined below) as a base class.109

M(X) is defined as follows:

  • If X is a non-union class type, the set M(X) is empty if X has no (possibly inherited (Clause 11.7 [class.derived])) non-static data members; otherwise, it consists of the type of the first non-static data member of X (where said member may be an anonymous union), X0, and the elements of M(X0).

  • If X is a union type, the set M(X), where each Ui is the type of the ith non-static data member of X, is the union of all M(Ui) and the set containing all Ui.

  • If X is a non-class type, the set M(X) is empty.

[Note: M(X) is the set of the types of all non-base-class subobjects that are guaranteed in a standard-layout class to be at a zero offset in X. —end note]

(See also the related changes in the resolution for issue 1813.)

Date: 2020-12-15.00:00:00

The layout compatibility rules of 11.4 [class.mem] paragraph 16 are phrased only in terms of non-static data members, ignoring the existence of base classes:

Two standard-layout struct (Clause Clause 11 [class]) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (6.8 [basic.types]).

However, this means that in an example like

  struct empty {};
  struct A { char a; };
  struct also_empty : empty {};
  struct C : empty, also_empty { char c; };
  union U {
    struct X { A a1, a2; } x;
    struct Y { C c1, c2; } y;
  } u;

u.x.a2.a and u.y.c2.c must have the same address, even though sizeof(A) would typically be 1 and sizeof(B) would need to be at least 2 to give the empty subobjects different addresses.

Date User Action Args
2017-02-06 00:00:00adminsetstatus: drwp -> cd4
2015-05-25 00:00:00adminsetstatus: dr -> drwp
2015-04-13 00:00:00adminsetmessages: + msg5391
2014-11-24 00:00:00adminsetstatus: tentatively ready -> dr
2014-10-13 00:00:00adminsetmessages: + msg5139
2014-10-13 00:00:00adminsetstatus: drafting -> tentatively ready
2013-10-14 00:00:00adminsetstatus: open -> drafting
2013-04-27 00:00:00admincreate