@@ -163,10 +163,16 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
163163< p >
164164< dt > < i > empty class</ i > </ dt >
165165< dd >
166- A class with no non-static data members other than zero-width bitfields,
166+ A class with no non-static data members other than zero-width bitfields
167+ and empty data members,
167168no virtual functions, no virtual base classes,
168169and no non-empty non-virtual proper base classes.
169170
171+ < p >
172+ < dt > < i > empty data member</ i > </ dt >
173+ < dd >
174+ A potentially-overlapping non-static data member of empty class type.
175+
170176< p >
171177< dt > < i > inheritance graph</ i > </ dt >
172178< dd >
@@ -267,12 +273,18 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
267273< dd >
268274< p >
269275In general, a type is considered a POD for the purposes of layout if
270- it is a POD type (in the sense of ISO C++ [basic.types]). However, a
271- POD-struct or POD-union (in the sense of ISO C++ [class]) with a
276+ it is a POD type (in the sense of ISO C++ [basic.types]).
277+ However, a type is not considered to be a POD for the purpose of layout
278+ if it is:
279+ < ul >
280+ < li > a POD-struct or POD-union (in the sense of ISO C++ [class]) with a
272281bitfield member whose declared width is wider than the declared type
273- of the bitfield is not a POD for the purpose of layout. Similarly, an
274- array type is not a POD for the purpose of layout if the element type
275- of the array is not a POD for the purpose of layout. Where references
282+ of the bitfield, or
283+ < li > an array type whose element type is not a POD for the purpose of layout, or
284+ < li > a POD-struct with one or more potentially-overlapping non-static
285+ data members.
286+ </ ul >
287+ Where references
276288to the ISO C++ are made in this paragraph, the Technical Corrigendum 1
277289version of the standard is intended.
278290</ p >
@@ -302,6 +314,12 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
302314</ p >
303315</ dd >
304316
317+ < p >
318+ < dt > < i > potentially-overlapping subobject</ i > </ dt >
319+ < dd >
320+ A base class subobject or a non-static data member declared with
321+ the < tt > [[no_unique_address]]</ tt > attribute.
322+
305323< p >
306324< dt > < i > primary base class</ i > </ dt > < dd > For a dynamic class, the
307325unique base class (if any) with which it shares the virtual pointer at
@@ -693,7 +711,6 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
693711
694712(See the description of these terms in
695713< a href =#general > < b > General</ b > </ a > above.)
696- Further, assume for data members that nvsize==size, and nvalign==align.
697714Layout (of type C) is done using the following procedure.
698715
699716< ol type =I >
@@ -832,7 +849,7 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
832849 and update sizeof(C) to max(sizeof(C),dsize(C)).
833850
834851 < p >
835- < li > If D is not an empty base class or D is a data member:
852+ < li > If D is not an empty base class and D is not an empty data member:
836853
837854 < p >
838855 Start at offset dsize(C),
@@ -856,28 +873,34 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
856873
857874 < p >
858875 If D is a base class, update sizeof(C) to max (sizeof(C),
859- offset(D)+nvsize(D)). Otherwise, if D is a data member,
876+ offset(D)+nvsize(D)).
877+ Otherwise, if D is a potentially-overlapping data member,
878+ update sizeof(C) to max (sizeof(C), offset(D)+max (nvsize(D), dsize(D))).
879+ Otherwise, if D is a data member,
860880 update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)).
861881
862882 < p >
863883 If D is a base class (not empty in this case),
864884 update dsize(C) to offset(D)+nvsize(D),
865885 and align(C) to max (align(C), nvalign(D)).
866- If D is a data member,
886+ If D is a potentially-overlapping data member,
887+ update dsize(C) to offset(D)+max (nvsize(D), dsize(D)),
888+ align(C) to max (align(C), align(D)).
889+ If D is any other data member,
867890 update dsize(C) to offset(D)+sizeof(D),
868891 align(C) to max (align(C), align(D)).
869892 </ p >
870893
871894 < p >
872- < li > If D is an empty proper base class:
895+ < li > If D is an empty proper base class or an empty data member :
873896
874897 < p >
875898 Its allocation is similar to case (2) above,
876899 except that additional candidate offsets are considered before
877900 starting at dsize(C).
878901 First, attempt to place D at offset zero.
879902 If unsuccessful (due to a component type conflict),
880- proceed with attempts at dsize(C) as for non-empty bases.
903+ proceed with attempts at dsize(C) as for non-empty bases and members .
881904 As for that case, if there is a type conflict at dsize(C)
882905 (with alignment updated as necessary),
883906 increment the candidate offset by nvalign(D),
@@ -886,9 +909,9 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
886909
887910 < p >
888911 Once offset(D) has been chosen, update sizeof(C) to max (sizeof(C),
889- offset(D)+sizeof(D)) and align(C) to max (alignof(C),
890- nvalign(D)). Since D is an empty base class, no update of
891- dsize(C) is needed.
912+ offset(D)+sizeof(D)), and update align(C) to max (alignof(C),
913+ nvalign(D)) for a base class or max (alignof(C), align(D)) for
914+ a data member. Since D is empty, no update of dsize(C) is needed.
892915
893916 </ ol >
894917
@@ -966,8 +989,19 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
966989< p >
967990< li > < h5 > Finalization </ h5 >
968991< p >
969- Round sizeof(C) up to a non-zero multiple of align(C). If C is a POD,
970- but not a POD for the purpose of layout, set nvsize(C) = sizeof(C).
992+ For each potentially-overlapping non-static data member D of C,
993+ update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)). Example:
994+
995+ < pre > < code >
996+ struct alignas(16) A { ~A(); }; // dsize 0, nvsize 0, size 16
997+ struct B : A {}; // dsize 0, nvsize 16, size 16
998+ struct X : virtual A, virtual B {}; // dsize 8, nvsize 8, size 32
999+ struct Y { [[no_unique_address]] X x; char c; }; // dsize 9, nvsize 9, size 32
1000+ </ code > </ pre >
1001+
1002+ < p >
1003+ Then, round sizeof(C) up to a non-zero multiple of align(C). If C is a POD,
1004+ but not a POD for the purpose of layout, set dsize(C) = nvsize(C) = sizeof(C).
9711005
9721006</ ol >
9731007
0 commit comments