This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


1719. Layout compatibility and cv-qualification revisited

Section: 11.4  [class.mem]     Status: CD4     Submitter: Jeffrey Yasskin     Date: 2013-07-24

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

When the effect of cv-qualification on layout compatibility was previously discussed (see issue 1334), the question was resolved by reference to the historical origin of layout compatibility: it was a weakening of type correctness that was added for C compatibility, mimicking exactly the corresponding C specification of compatible types in this context and going no further. Because cv-qualified and cv-unqualified types are not compatible in C, they were not made layout-compatible in C++.

Because of specific use-cases involving std::pair and the like, however, and in consideration of the fact that cv-qualified and cv-unqualified versions of types are aliasable by the rules of 7.2.1 [basic.lval], the outcome of that question is worthy of reconsideration.

Proposed resolution (June, 2014):

  1. Change 6.1 [basic.pre] paragraph 3 as follows:

  2. An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, parameter pack, or this.
  3. Change 6.8 [basic.types] paragraph 11 as follows:

  4. If two types T1 and T2 are the same type, then T1 and T2 Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, layout-compatible enumerations (9.7.1 [dcl.enum]), or layout-compatible standard-layout class types (11.4 [class.mem]). [Note: Layout-compatible enumerations are described in 9.7.1 [dcl.enum]. Layout-compatible standard-layout structs and standard-layout unions are described in 11.4 [class.mem]. —end note]
  5. Change 6.8.4 [basic.compound] paragraph 3 as follows:

  6. ...The value representation of pointer types is implementation-defined. Pointers to cv-qualified and cv-unqualified versions (6.8.5 [basic.type.qualifier]) of layout-compatible types shall have the same value representation and alignment requirements (6.7.6 [basic.align]). [Note:...
  7. Insert the following as a new paragraph before 11.4 [class.mem] paragraph 16 and change paragraphs 16 through 18 as follows:

  8. The common initial sequence of two standard-layout struct (Clause 11 [class]) 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 and either neither entity is a bit-field or both are bit-fields with the same width. [Example:

      struct A { int a; char b; };
      struct B { const int b1; volatile char b2; };
      struct C { int c; unsigned : 0; char b; };
      struct D { int d; char b : 4; };
      struct E { unsigned int e; char b; };
    

    The common initial sequence of A and B comprises all members of either class. The common initial sequence of A and C and of A and D comprises the first member in each case. The common initial sequence of A and E is empty. —end example]

    Two standard-layout struct (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 their common initial sequence comprises all members and bit-fields of both classes (6.8 [basic.types]).

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

    If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members. In a standard-layout union with an active member (11.5 [class.union]) of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2. [Note: Reading a volatile object through a non-volatile glvalue has undefined behavior (9.2.9.2 [dcl.type.cv]). —end note]