Name n3875, alx-0086r5 - comparable types Principles - Keep the language small and simple Category Editorial Author Christopher Bazley Alejandro Colomar Cc: Philipp Klaus Krause Cc: Aaron Ballman Cc: Joseph Myers History r0 (2026-02-06): - Initial draft. Fork from n3674. r1 (2026-02-10; n3844): - Document the term access qualifiers. - Add n3795 to See also. r2 (2026-03-25): - Rebase on n3854. - Update J.2. - Change footnote to NOTE paragraph. - Add footnote clarifying that only top-level qualifiers are intended by the paragraph. - Update 6.5.1 to use comparable type. - tfix. r3 (2026-03-31): - ffix - Remove author. - Update footnote numbers. r4 (2026-04-07): - Clarify relationship with other proposals. - Clarify why some text is removed (it's redundant now). - We replace q or unq versions of a compatible type, not just any q or unq type. - Replace a couple of other places. r5 (2026-04-11; n3875): - Disallow I-D access qualifiers. This makes the paper fully editorial. - Mention n1275 as the first use of 'access qualifiers' that I know of. Description Too often, we use the phrase "qualified or unqualified version of a compatible type". It implicitly does not include the _Atomic qualifier. Let's use a specific term for that: "comparable type". Before this proposal, the only qualifiers allowed by the standard were 'const', 'restrict', and 'volatile'. That remains true after this paper. Nevertheless, the wording of this paper makes it easy to: - Add a sentence allowing other implementation-defined access qualifiers (FWIW, previous revisions of this paper allowed them). - Add other classes of qualifiers (but this will require some more work). Relationship with other proposals This is a preparation for (spin off from) n3745 (which is itself a spin-off from n3674). n3745 was voted along the lines in Brno: Opinion Poll: Would WG14 like to adopt something along the lines of N3629 into C2y? 3-0-1 + 18-0-5 = 23-0-6 Admittedly, I've changed the wording significantly from n3745, so none of the text in n3844 comes from n3745. Rather, I followed the text from Chris's type variance paper: n3674. That paper was voted along the lines in 202602: Opinion Poll: Would WG14 like to adopt something along the lines of N3674 into C2y? 19-0-8 strong direction I took the wording about comparable types almost exactly from that paper, with very small fixes. So we have indeed reviewed this wording in a meeting; almost the exact wording, indeed. And, I took the access qualifier term from Philipp's paper: n3795. Although I took it much simpler, since I didn't add any other kinds of qualifiers. Of course, we also voted that paper along the lines, in 202603: Opinion Poll: Do we want the "access qualifier" concept along the lines of N3795 in C2y? 11-4-8 direction in favor The oldest paper I know of that uses the term 'access qualifiers' (if there are any older ones, I don't know them) is . See also Proposed wording Based on N3854. 6.2.5 Types @@ p37+1 +The +const, +restrict, +and +volatile +qualifiers +are collectively called +the access qualifiers. @@ p38 Any type so far mentioned is an unqualified type. Each unqualified type has several qualified versions of its type,30) corresponding to the combinations of -one, two, or all three of -the const, volatile, and restrict qualifiers. +some or all access qualifiers. The qualified or unqualified versions of a type are distinct types that belong to -the same type category +the same type category. -and have the same representation and alignment requirements.31) An array and its element type are always considered to be identically qualified.32) Any other derived type is not qualified by the qualifiers (if any) of the type from which it is derived. ## The above (and its footnote) will be now covered by ## comparable type rules (see 6.2.7+1 below), which makes this ## redundant, and thus removed. Types in the same type category ## are comparable types. @@ Footnote 31 -31) -The same representation and alignment requirements -are meant to imply interchangeability as -arguments to functions, -return values from functions, -and members of unions. 6.2.6.3 Pointer types and nullptr_t @@ p1 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.41) Similarly, pointers to -qualified or unqualified versions of compatible types +comparable types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types may not have the same representation or alignment requirements. ## This guarantees that char** and const char*const* have the ## same representation and alignment. 6.2 Concepts ## Add new subsections after 6.2.7 ("Compatible type and composite type") +6.2.7+1 Comparable type +1 + Two types are comparable types + if they would be compatible types + if all access qualifiers + were removed from both types. + XXX) +2 + Comparable complete object types + shall have the same + representation and alignment requirements. +3 + NOTE + The same representation and alignment requirements + are meant to imply interchangeability as + arguments to functions, + return values from functions, + and members of unions. + +XXX) + Only top-level qualifiers. 6.5.1 Expressions :: General @@ Semantics, p9 An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 71) -- - a type compatible with + a type comparable with the effective type of the object, - -- - a qualified version of - a type compatible with - the effective type of the object, -- the signed or unsigned type corresponding to - a type compatible with + a type comparable with the underlying type of the effective type of the object, - -- - the signed or unsigned type corresponding to - a type compatible with - a qualified version of - the underlying type of - the effective type of the object, -- [...] -- [...] 6.5.7 Additive operators @@ Constraints, p3 For subtraction, one of the following shall hold: -- [...] -- both operands are pointers to - qualified or unqualified versions of compatible + comparable complete object types; or -- [...] 6.5.9 Relational operators @@ Constraints, p2 One of the following shall hold: -- [...] -- both operands are pointers to - qualified or unqualified versions of compatible + comparable object types. 6.5.10 Equality operators @@ Constraints, p2 One of the following shall hold: -- [...] -- both operands are pointers to - qualified or unqualified versions of compatible + comparable types. -- one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; -- [...] -- [...] -- [...] 6.5.16 Conditional operator @@ Constraints, p3 One of the following shall hold for the second and third operands:93) -- [...] -- [...] -- [...] -- both operands are pointers to - qualified or unqualified versions of compatible + comparable types; -- [...] -- [...] -- [...] @@ Semantics, p8 If both the second and third operands are pointers, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands; if one is a null pointer constant (other than a pointer) or has type nullptr_t and the other is a pointer, the result type is the pointer type; if both the second and third operands have nullptr_t type, the result also has that type. Furthermore, if both operands are pointers to -compatible types -or to differently qualified versions of compatible types, +comparable types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void. 6.5.17.2 Expressions :: Assignment operators :: Simple assignment @@ Constraints, p1 One of the following shall hold:96) -- [...] -- [...] -- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to - qualified or unqualified versions of compatible + comparable types, and the type pointed to by the left operand has all the qualifiers of the type pointed to by the right operand; -- [...] -- [...] -- [...] -- [...] @@ Semantics, p3 If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the two objects shall occupy exactly the same storage and shall have -qualified or unqualified versions of a compatible +comparable type; otherwise, the behavior is undefined. 6.7.11 Initialization @@ Constraints, p7 The initializer for an array shall be: ... An array initialized by a character string literal or UTF-8 string literal shall have a character type as element type. An array initialized with a wide string literal shall have element type -compatible with a qualified or unqualified +comparable with wchar_t, char16_t, or char32_t, and the string literal shall have the corresponding encoding prefix (L, u, or U, respectively). 7.16.2.2 The va_arg macro @@ Description, p2 ... except for the following cases: -- both types are pointers to - qualified or unqualified versions of compatible + comparable types; -- [...] -- [...] -- [...]