Name
n3931, alx-0086r7 - comparable types
Principles
- Keep the language small and simple
Category
Editorial
Author
Christopher Bazley <chris.bazley.wg14@gmail.com>
Alejandro Colomar <alx@kernel.org>
Cc: Philipp Klaus Krause <philipp@informatik.uni-frankfurt.de>
Cc: Aaron Ballman <aaron@aaronballman.com>
Cc: Joseph Myers <josmyers@redhat.com>
History
<https://www.alejandro-colomar.es/src/alx/alx/std/wg14/alx-0086.git/>
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, n3870):
- 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.
r6 (2026-04-17):
- Refer to correct paper numbers.
- Remove changes to 6.5.1 (they're moved to alx-0091).
r7 (2026-07-13; n3931):
- Remove 'shall' not in 'Constraints'.
- Fix link.
- Minimize diff.
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) n3749 (which is itself
a spin-off from n3674). n3749 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 n3749,
so none of the text in alx-0086 comes from n3749. 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
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1275.pdf>.
See also
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3749.txt>
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3674.pdf>
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3795.pdf>
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1275.pdf>
Proposed wording
Based on N3854.
6.2.5 Types
@@ p37+1
+The
+<b>const</b>,
+<b>restrict</b>,
+and
+<b>volatile</b>
+qualifiers
+are collectively called
+the <i>access qualifiers<i>.
@@ 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
-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 <i>comparable types</i>
+ if they would be compatible types
+ if all access qualifiers
+ were removed from both types.
+ XXX)
+2
+ Comparable complete object types
+ 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.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;
-- [...]
-- [...]
-- [...]