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;
	  --	[...]
	  --	[...]
	  --	[...]