This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Accepted as a DR at the November, 2023 meeting.]
The interaction of [[no_unique_address]] and the definition of common initial sequence is still problematic. Subclause 11.4.1 [class.mem.general] bullet 23.3 specifies that corresponding members in a common initial sequence are not allowed to differ with respect to the presence or absence of a [[no_unique_address]] attribute. However, the Itanium ABI will not allocate two successive data members of the same empty class type at the same address, causing non-conforming behavior for the following example:
struct A {}; struct B {}; struct C { [[no_unique_address]] A a; [[no_unique_address]] B b; }; struct D { [[no_unique_address]] A a1; [[no_unique_address]] A a2; }; static_assert(offsetof(C, b) == offsetof(D, a2));
Since "common initial sequence" and "layout compatible" are concepts mostly used for C compatibility, but [[no_unique_address]] does not exist in C, it seems reasonable to terminate a common initial sequence at the first data member that is declared [[no_unique_address]].
Another concern is the behavior of std::is_layout_compatible on implementations that ignore [[no_unique_address]]. On such an implementation, the following example would be considered layout-compatible, although it actually is not:
struct E {}; struct A { E e; int i; }; struct B { [[no_unique_address]] E e; int i; }; static_assert( std::is_layout_compatible_v<A, B> );
Alternative possible resolution [SUPERSEDED]:
Change in 11.4.1 [class.mem.general] paragraph 23 as follows:
The common initial sequence of two standard-layout struct (11.2 [class.prop]) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that
- corresponding entities have layout-compatible types (6.8 [basic.types]),
- corresponding entities have the same alignment requirements (6.7.3 [basic.align]),
either both entities are declared with the no_unique_address attribute (9.12.12 [dcl.attr.nouniqueaddr]) or neither is,neither entity is declared with the no_unique_address attribute (9.12.12 [dcl.attr.nouniqueaddr]), and- either both entities are bit-fields with the same width or neither is a bit-field.
Proposed resolution (approved by CWG 2023-08-25):
Change in 11.4.1 [class.mem.general] paragraph 23 as follows:
The common initial sequence of two standard-layout struct (11.2 [class.prop]) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that
- corresponding entities have layout-compatible types (6.8 [basic.types]),
- corresponding entities have the same alignment requirements (6.7.3 [basic.align]),
either both entities are declared with the no_unique_address attribute (9.12.12 [dcl.attr.nouniqueaddr]) or neither is,if a has-attribute-expression (15.2 [cpp.cond]) is not 0 for the no_unique_address attribute, then neither entity is declared with the no_unique_address attribute (9.12.12 [dcl.attr.nouniqueaddr]), and- either both entities are bit-fields with the same width or neither is a bit-field.