@@ -163,11 +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,
166+ A class with no non-static data members other than empty data members ,
167167no unnamed bit-fields other than zero-width bit-fields,
168168no virtual functions, no virtual base classes,
169169and no non-empty non-virtual proper base classes.
170170
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+
171176< p >
172177< dt > < i > inheritance graph</ i > </ dt >
173178< dd >
@@ -268,14 +273,18 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
268273< dd >
269274< p >
270275In general, a type is considered a POD for the purposes of layout if
271- it is a POD type (in the sense of ISO C++ [basic.types]). However, a
272- 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]). However, a
277+ type is not considered to be a POD for the purpose of layout if it is:
278+ < ul >
279+ < li > a POD-struct or POD-union (in the sense of ISO C++ [class]) with a
273280bit-field whose declared width is wider than the declared type
274- of the bit-field is not a POD for the purpose of layout. Similarly, an
275- array type is not a POD for the purpose of layout if the element type
276- of the array is not a POD for the purpose of layout. Where references
277- to the ISO C++ are made in this paragraph, the Technical Corrigendum 1
278- version of the standard is intended.
281+ of the bit-field, or
282+ < li > an array type whose element type is not a POD for the purpose of layout, or
283+ < li > a POD-struct with one or more potentially-overlapping non-static
284+ data members.
285+ </ ul >
286+ Where references to the ISO C++ are made in this paragraph, the Technical
287+ Corrigendum 1 version of the standard is intended.
279288</ p >
280289
281290< p >
@@ -303,6 +312,12 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
303312</ p >
304313</ dd >
305314
315+ < p >
316+ < dt > < i > potentially-overlapping subobject</ i > </ dt >
317+ < dd >
318+ A base class subobject or a non-static data member declared with
319+ the < tt > [[no_unique_address]]</ tt > attribute.
320+
306321< p >
307322< dt > < i > primary base class</ i > </ dt > < dd > For a dynamic class, the
308323unique base class (if any) with which it shares the virtual pointer at
@@ -694,7 +709,6 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
694709
695710(See the description of these terms in
696711< a href =#general > < b > General</ b > </ a > above.)
697- Further, assume for data members that nvsize==size, and nvalign==align.
698712Layout (of type C) is done using the following procedure.
699713
700714< ol type =I >
@@ -833,7 +847,7 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
833847 and update sizeof(C) to max(sizeof(C),dsize(C)).
834848
835849 < p >
836- < li > If D is not an empty base class or D is a data member:
850+ < li > If D is not an empty base class and D is not an empty data member:
837851
838852 < p >
839853 Start at offset dsize(C),
@@ -857,28 +871,34 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
857871
858872 < p >
859873 If D is a base class, update sizeof(C) to max (sizeof(C),
860- offset(D)+nvsize(D)). Otherwise, if D is a data member,
874+ offset(D)+nvsize(D)).
875+ Otherwise, if D is a potentially-overlapping data member,
876+ update sizeof(C) to max (sizeof(C), offset(D)+max (nvsize(D), dsize(D))).
877+ Otherwise, if D is a data member,
861878 update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)).
862879
863880 < p >
864881 If D is a base class (not empty in this case),
865882 update dsize(C) to offset(D)+nvsize(D),
866883 and align(C) to max (align(C), nvalign(D)).
867- If D is a data member,
884+ If D is a potentially-overlapping data member,
885+ update dsize(C) to offset(D)+max (nvsize(D), dsize(D)),
886+ align(C) to max (align(C), align(D)).
887+ If D is any other data member,
868888 update dsize(C) to offset(D)+sizeof(D),
869889 align(C) to max (align(C), align(D)).
870890 </ p >
871891
872892 < p >
873- < li > If D is an empty proper base class:
893+ < li > If D is an empty proper base class or an empty data member :
874894
875895 < p >
876896 Its allocation is similar to case (2) above,
877897 except that additional candidate offsets are considered before
878898 starting at dsize(C).
879899 First, attempt to place D at offset zero.
880900 If unsuccessful (due to a component type conflict),
881- proceed with attempts at dsize(C) as for non-empty bases.
901+ proceed with attempts at dsize(C) as for non-empty bases and members .
882902 As for that case, if there is a type conflict at dsize(C)
883903 (with alignment updated as necessary),
884904 increment the candidate offset by nvalign(D),
@@ -887,9 +907,9 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
887907
888908 < p >
889909 Once offset(D) has been chosen, update sizeof(C) to max (sizeof(C),
890- offset(D)+sizeof(D)) and align(C) to max (alignof(C),
891- nvalign(D)). Since D is an empty base class, no update of
892- dsize(C) is needed.
910+ offset(D)+sizeof(D)), and update align(C) to max (alignof(C),
911+ nvalign(D)) for a base class or max (alignof(C), align(D)) for
912+ a data member. Since D is empty, no update of dsize(C) is needed.
893913
894914 </ ol >
895915
@@ -967,8 +987,19 @@ <h3><a href="#class-types"> 2.4 Non-POD Class Types </a></h3>
967987< p >
968988< li > < h5 > Finalization </ h5 >
969989< p >
970- Round sizeof(C) up to a non-zero multiple of align(C). If C is a POD,
971- but not a POD for the purpose of layout, set nvsize(C) = sizeof(C).
990+ For each potentially-overlapping non-static data member D of C,
991+ update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)). Example:
992+
993+ < pre > < code >
994+ struct alignas(16) A { ~A(); }; // dsize 0, nvsize 0, size 16
995+ struct B : A {}; // dsize 0, nvsize 16, size 16
996+ struct X : virtual A, virtual B {}; // dsize 8, nvsize 8, size 32
997+ struct Y { [[no_unique_address]] X x; char c; }; // dsize 9, nvsize 9, size 32
998+ </ code > </ pre >
999+
1000+ < p >
1001+ Then, round sizeof(C) up to a non-zero multiple of align(C). If C is a POD,
1002+ but not a POD for the purpose of layout, set dsize(C) = nvsize(C) = sizeof(C).
9721003
9731004</ ol >
9741005
0 commit comments