From 90812884adf9a04672177da1b677c0c9a42a1e74 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 13:43:21 -0700 Subject: [PATCH 01/32] CWG2609 Padding in class types --- source/expressions.tex | 2 ++ source/intro.tex | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 10fffe4f88..274ccd467b 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -5675,6 +5675,8 @@ When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array. +The amount and placement of padding in a class type +is a property of the implementation. The result of applying \keyword{sizeof} to a potentially-overlapping subobject is the size of the type, not the size of the subobject. diff --git a/source/intro.tex b/source/intro.tex index b04be9ab9d..a19f0ad556 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -339,6 +339,11 @@ \definition{implementation limit}{defns.impl.limits} restriction imposed upon programs by the implementation +\indexdefn{prop!implementation}% +\definition{property of the implementation}{defns.impl.prop} +behavior, for a well-formed program\iref{defns.well.formed} +construct and correct data, that depends on the implementation + \indexdefn{behavior!locale-specific}% \definition{locale-specific behavior}{defns.locale.specific} behavior that depends on local conventions of nationality, culture, and @@ -920,10 +925,14 @@ \pnum \indextext{behavior!implementation-defined}% -Certain aspects and operations of the abstract machine are described in this +Certain aspects and operations of the abstract machine +constitute the parameters of the abstract machine and +are described in this document as implementation-defined behavior (for example, -\tcode{sizeof(int)}). These constitute the parameters of the abstract machine. -Each implementation shall include documentation describing its characteristics +\tcode{sizeof(int)}) +or as properties of the implementation (for example, padding in class types). +For implementation-defined behavior, +each implementation shall include documentation describing its characteristics and behavior in these respects. \begin{footnote} This documentation also includes From e3568c82a8e15f454cf4df19922186c9742d2ccc Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 14:09:47 -0700 Subject: [PATCH 02/32] CWG2744 Multiple objects of the same type at the same address --- source/basic.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index e9ce2c1e8e..baa641a792 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3640,7 +3640,12 @@ may have the same address if \begin{itemize} \item one is nested within the other, -\item at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, +\item +they are both nested within some complete object $o$, +exactly one is a subobject of $o$, and the subobject is of zero size, +\item +they are both subobjects of the same complete object, +at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, or \item they are both potentially non-unique objects; \end{itemize} From eb45559c0f86b8717a7af4b275d6a0a7b3fb97d4 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 15:22:18 -0700 Subject: [PATCH 03/32] CWG2765 Address comparisons between potentially non-unique objects during constant evaluation --- source/basic.tex | 22 ++++++++++++++++++++++ source/expressions.tex | 41 +++++++++++++++++++++++++++++++++++++++++ source/utilities.tex | 11 ++--------- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index baa641a792..64d0c5bf18 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5984,6 +5984,28 @@ alignment requirement. \end{note} +\pnum +A pointer value +pointing to a potentially non-unique object $O$\iref{intro.object} is +\indextext{value!associated with an evaluation}% +\defn{associated with} the evaluation of +\begin{itemize} +\item +the string-literal\iref{lex.string} that resulted in the string literal object, +\item +the initializer list\iref{dcl.init.list} that resulted in the backing array, +or +\item +the initialization of +the template parameter object\iref{temp.arg.nontype, meta.define.static} +\end{itemize} +that is $O$ or of which $O$ is a subobject. +\begin{note} +A pointer value obtained by pointer arithmetic\iref{expr.add} +from a pointer value associated with an evaluation $E$ +is also associated with $E$. +\end{note} + \pnum A pointer value $P$ is \indextext{value!valid in the context of an evaluation}% diff --git a/source/expressions.tex b/source/expressions.tex index 274ccd467b..51b80b2dcf 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -8329,6 +8329,19 @@ \rSec2[expr.const.core]{Core constant expressions} +\pnum +\indextext{type!constexpr-unknown representation}% +A type has \defnadj{constexpr-unknown}{representation} if it +\begin{itemize} +\item is a union, +\item is a pointer or pointer-to-member type, +\item is volatile-qualified, +\item is a class type with a non-static data member of reference type, or +\item +has a base class or a non-static member whose +type has constexpr-unknown representation. +\end{itemize} + \pnum An expression $E$ is a \defnadj{core constant}{expression} unless the evaluation of $E$, following the rules of the abstract @@ -8556,6 +8569,34 @@ relational\iref{expr.rel}, or equality\iref{expr.eq} operator where the result is unspecified; +\item +an equality operator comparing pointers to potentially non-unique objects, +if the pointer values of the two operands +are associated with different evaluations\iref{basic.compound} and either +they can both point to the same offset within +the same potentially non-unique object or +one of them points to an object whose +type has constexpr-unknown representation; +\begin{example} +\begin{codeblock} +constexpr const char *f() { return "foo"; } + +constexpr bool b1 = +"foo" == "foo"; // error: non-constant +constexpr bool b2 = f() == f(); // error: non-constant +constexpr const char *p = f(); +constexpr bool b3 = p == p; // OK, value of \tcode{b3} is \tcode{true} +constexpr bool b4 = "xfoo" + 1 == "foo\0y"; // error: non-constant; string literal + // object could contain \tcode{"xfoo\textbackslash{}0y"} +constexpr bool b5 = "foo" == "bar" + 0; // OK, value of \tcode{b5} is \tcode{false} +constexpr bool b6 = (const char*)"foo" == "oo"; // OK, value of \tcode{b6} is \tcode{false}; offsets would + // be different in a merged string literal object + +constexpr std::initializer_list il1 = { (int *)nullptr }; +constexpr std::initializer_list il2 = { 0 }; +constexpr bool b7 = il1.begin() == (void *)il2.begin(); // error: non-constant +\end{codeblock} +\end{example} + \item a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression diff --git a/source/utilities.tex b/source/utilities.tex index 09be66f705..04e397bb6c 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15943,15 +15943,8 @@ \pnum \constantwhen -\tcode{To}, \tcode{From}, and the types of all subobjects -of \tcode{To} and \tcode{From} are types \tcode{T} such that: -\begin{itemize} -\item \tcode{is_union_v} is \tcode{false}; -\item \tcode{is_pointer_v} is \tcode{false}; -\item \tcode{is_member_pointer_v} is \tcode{false}; -\item \tcode{is_volatile_v} is \tcode{false}; and -\item \tcode{T} has no non-static data members of reference type. -\end{itemize} +Neither \tcode{To} nor \tcode{From} +has constexpr-unknown representation\iref{expr.const}. \pnum \returns From c0a95fd4e8143679a60bfb87a3c64a5dce8ea82e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 15:24:16 -0700 Subject: [PATCH 04/32] CWG2799 Inheriting default constructors --- source/overloading.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/overloading.tex b/source/overloading.tex index fe6c4d0852..f6910d355b 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1056,7 +1056,8 @@ class. The argument list is the \grammarterm{expression-list} or \grammarterm{assignment-expression} -of the \grammarterm{initializer}. +of the \grammarterm{initializer}; +for default-initialization, the argument list is empty. For default-initialization in the context of copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed. From 8b678561bce78f92ae4779f0f52acde59964bb01 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:01:47 -0700 Subject: [PATCH 05/32] CWG2947 Limiting macro expansion in pp-module --- source/preprocessor.tex | 80 ++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index f8bd97288f..5459b62a51 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1224,7 +1224,7 @@ \begin{bnf} \nontermdef{pp-module}\br - \opt{\keyword{export}} \keyword{module} \opt{pp-tokens} \terminal{;} new-line + \opt{\keyword{export}} \keyword{module} \opt{pp-tokens} new-line \end{bnf} \pnum @@ -1233,8 +1233,7 @@ \begin{ncsimplebnf} pp-module-name \opt{pp-module-partition} \opt{pp-tokens} \end{ncsimplebnf} -where the \grammarterm{pp-tokens} (if any) shall not begin with -a \tcode{(} preprocessing token and +where the grammar non-terminals are defined as: \begin{ncbnf} \nontermdef{pp-module-name}\br @@ -1251,15 +1250,9 @@ \end{ncbnf} No \grammarterm{identifier} in the \grammarterm{pp-module-name} or \grammarterm{pp-module-partition} -shall currently be defined as an object-like macro. - -\pnum -Any preprocessing tokens after the \tcode{module} preprocessing token -in the \tcode{module} directive are processed just as in normal text. -\begin{note} -Each identifier currently defined as a macro name -is replaced by its replacement list of preprocessing tokens. -\end{note} +shall currently be defined as an object-like macro +or followed by \tcode{(} as the next preprocessing token at +the start of phase 4 of translation\iref{lex.phases}. \pnum The \tcode{module} and \tcode{export} (if it exists) preprocessing tokens @@ -1269,6 +1262,69 @@ This makes the line no longer a directive so it is not removed at the end of phase 4. \end{note} +After this replacement, +the preprocessing tokens that constituted the directive are +a \grammarterm{text-line} and are processed as normal text. +\begin{note} +No macro expansion is possible for +the \grammarterm{pp-module-name} and \grammarterm{pp-module-partition}. +\end{note} +After such processing, +there shall be a \tcode{;} or \tcode{[} preprocessing token following +the \grammarterm{pp-module-name} and +optional \grammarterm{pp-module-partition}. + +\pnum +\begin{example} +\begin{codeblocktu}{Importable header \tcode{"common.h"}} +#define DOT_BAR .bar +#define MOD_ATTR [[vendor::shiny_module]] +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \tcode{\#1}} +module; +#include "common.h" + +export module foo DOT_BAR; // error: expansion of \tcode{DOT_BAR}; does not begin with \tcode{;} or \tcode{[} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \tcode{\#2}} +module; +#include "common.h" + +export module M MOD_ATTR ; // OK +\end{codeblocktu} +\end{example} + +\begin{example} +\begin{codeblock} +export module a +.b; // error: preprocessing token after pp-module-name is not ; or [ +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +export module M [[ +attr1, +attr2 ]] ; // OK +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +export module M +[[ attr1, +attr2 ]] ; // OK +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +export module M; int +n; // OK +\end{codeblock} +\end{example} \rSec1[cpp.import]{Header unit importation} \indextext{header unit!preprocessing}% From 280c60dcd2445762f4f467e497d7c6f274aa8862 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:12:50 -0700 Subject: [PATCH 06/32] CWG2966 Alignment and value representation of std::nullptr_t --- source/basic.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index 64d0c5bf18..2189ab5253 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5665,7 +5665,12 @@ A prvalue of type \tcode{std::nullptr_t} is a null pointer constant\iref{conv.ptr}. Such values participate in the pointer and the pointer-to-member conversions\iref{conv.ptr,conv.mem}. -\tcode{\keyword{sizeof}(std::nullptr_t)} shall be equal to \tcode{\keyword{sizeof}(\keyword{void}*)}. +The size\iref{expr.sizeof} and alignment requirement\iref{basic.align} of +the type \tcode{std::nullptr_t} are those of +the type ``pointer to \keyword{void}''. +\begin{note} +The value representation can comprise no bits\iref{conv.lval}. +\end{note} \pnum A value of type \tcode{std::meta::info} is called a \defn{reflection}. From 351866dd6d347b437995cb4ededaf58969480c14 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:16:33 -0700 Subject: [PATCH 07/32] CWG2976 Transferring control out of a function --- source/statements.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/statements.tex b/source/statements.tex index 9163c1916a..07760a4ed4 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -1300,7 +1300,8 @@ after its \grammarterm{init-declarator}. \indextext{initialization!jump past}% \indextext{\idxcode{goto}!initialization and}% -Upon each transfer of control (including sequential execution of statements) +Upon each transfer of control (including sequential execution of statements, +but excluding function calls) within a function from point $P$ to point $Q$, all block variables with automatic storage duration that are active at $P$ and not at $Q$ are destroyed in the reverse order of their construction. From 273398dd6a134ab33ad2f88abc4a7897b900682c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:53:58 -0700 Subject: [PATCH 08/32] CWG2983 Non-type template parameters are not variables --- source/basic.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 2189ab5253..2dbf4724c6 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -115,13 +115,15 @@ \pnum A \defn{variable} is introduced by the -declaration of +declaration $D$ of \begin{itemize} \item a reference other than a non-static data member or \item -an object. +an object, \end{itemize} +where $D$ is not the \grammarterm{parameter-declaration} of +a \grammarterm{template-parameter}. \pnum An \defn{entity} is a From 37be8a3ed09ddf20feb3fce547be4282a58ccb8f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 18:42:09 -0700 Subject: [PATCH 09/32] CWG2992 Labels do not have names --- source/basic.tex | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 2dbf4724c6..51423f161d 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -32,10 +32,26 @@ \end{note} \pnum -A \defn{name} is an \grammarterm{identifier}\iref{lex.name}, -\grammarterm{conversion-function-id}\iref{class.conv.fct}, -\grammarterm{operator-function-id}\iref{over.oper}, or -\grammarterm{literal-operator-id}\iref{over.literal}. +A \defn{name} is +\begin{itemize} +\item an \grammarterm{identifier} token\iref{lex.token, lex.name} other than + \begin{itemize} + \item + the \grammarterm{identifier} of a + \grammarterm{label}\iref{stmt.label} or + \grammarterm{literal-operator-id}\iref{over.literal}, + \item + the \grammarterm{identifier} following a goto in a + \grammarterm{jump-statement}\iref{stmt.jump.general}, + \item + any \grammarterm{identifier} in a + \grammarterm{module-name}\iref{module.unit} or + \grammarterm{attribute-token}\iref{dcl.attr.grammar}, or + \end{itemize} +\item a \grammarterm{conversion-function-id}\iref{class.conv.fct}, +\item an \grammarterm{operator-function-id}\iref{over.oper}, or +\item a \grammarterm{literal-operator-id}\iref{over.literal}. +\end{itemize} \pnum Two names are \defnx{the same}{name!same} if From 5caf7efac5bc9b8399175d4786a880583154aaa8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:01:46 -0700 Subject: [PATCH 10/32] CWG3010 constexpr placement-new should require transparent replaceability --- source/expressions.tex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 51b80b2dcf..0b12ccbe1e 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -8520,10 +8520,11 @@ with an allocated type \tcode{T}, where \begin{itemize} \item -the placement argument to the \grammarterm{new-expression} points to -an object whose type is similar to \tcode{T}\iref{conv.qual} or, -if \tcode{T} is an array type, -to the first element of an object of a type similar to \tcode{T}, and +the placement argument to the \grammarterm{new-expression} points +to an object that is transparently replaceable\iref{basic.life} by +the object created by the \grammarterm{new-expression} +or, if \tcode{T} is an array type, +to the first element of such an object, and \item the placement argument points to storage whose duration began within the evaluation of $E$; From d88021f4b4f2a23c6e0ec646d7d605ec1bd69234 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:09:09 -0700 Subject: [PATCH 11/32] CWG3029 Confusing note about ordinary character types for aligned memory areas --- source/basic.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 51423f161d..a1cdd6a3c6 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3850,8 +3850,8 @@ the narrow character types\iref{basic.fundamental} shall have the weakest alignment requirement. \begin{note} -This enables the ordinary character types to be used as the -underlying type for an aligned memory area\iref{dcl.align}. +The type \tcode{\keyword{unsigned} \keyword{char}} can be used as +the element type of an array providing aligned storage\iref{dcl.align}. \end{note} \pnum From 509f5656fb3a77518f6362ea72aebc9c240cbe31 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:27:26 -0700 Subject: [PATCH 12/32] CWG3035 Lambda expressions in anonymous unions --- source/classes.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 058a317666..18afda563d 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -3272,7 +3272,9 @@ of an anonymous union shall define one or more public non-static data members, be an \grammarterm{empty-declaration}, or be a \grammarterm{static_assert-declaration}. -Nested types, anonymous unions, and functions +Nested types +(including closure types\iref{expr.prim.lambda.closure} and anonymous unions) +and functions shall not be declared within an anonymous union. The names of the members of an anonymous union are bound in the scope inhabited by the union declaration. From c19df8614e2f23ddb08cb60a3b9710764d6bce9c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 20:28:57 -0700 Subject: [PATCH 13/32] CWG3058 "Program point" is not defined Fixes NB US 14-029 (C++26 CD). --- source/basic.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/basic.tex b/source/basic.tex index a1cdd6a3c6..7c76b49ae6 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1678,6 +1678,11 @@ used in further processing. \pnum +There is a \defnadj{program}{point} +before the first token of the translation unit, +at least one between every pair of adjacent tokens, and +at least one after the last token of the translation unit. + A program point $P$ is said to follow any declaration in the same translation unit whose locus\iref{basic.scope.pdecl} is before $P$. From 6e4aaee526916ac13ceecb6e3272cdf1bcee78bb Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 01:21:53 -0700 Subject: [PATCH 14/32] CWG3125 Token convertibility requirement in #if --- source/preprocessor.tex | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 5459b62a51..abf67872bd 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -508,12 +508,6 @@ The identifiers \xname{has_include}, \xname{has_embed}, and \xname{has_cpp_attribute} shall not appear in any context not mentioned in this subclause. -\pnum -Each preprocessing token that remains (in the list of preprocessing tokens that -will become the controlling expression) -after all macro replacements have occurred -shall be in the lexical form of a token\iref{lex.token}. - \pnum Preprocessing directives of the forms \begin{ncsimplebnf} From 3b7c41ead6fb5b3f249a8616b9af0b7a21f49942 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 01:28:12 -0700 Subject: [PATCH 15/32] CWG3126 A module import needs a header-name as a token --- source/lex.tex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/lex.tex b/source/lex.tex index 7547b4aa69..ef2687ddf1 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -585,6 +585,7 @@ \pnum Each preprocessing token that is converted to a token\iref{lex.token} shall have the lexical form of a keyword, an identifier, a literal, +a header name, or an operator or punctuator. \pnum @@ -872,12 +873,14 @@ identifier\br keyword\br literal\br + header-name\br operator-or-punctuator \end{bnf} \pnum \indextext{\idxgram{token}}% -There are five kinds of tokens: identifiers, keywords, literals, +There are six kinds of tokens: identifiers, keywords, literals, +header names, operators, and other separators. \indextext{token|)} From d27a00495d60d17e27b0075f8d32ce56818a3cb8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:07:17 -0700 Subject: [PATCH 16/32] CWG3128 Potentially-throwing unevaluated operands --- source/exceptions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 29d4357749..377a0a8237 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -887,7 +887,7 @@ or \item any of the immediate subexpressions\iref{intro.execution} -of $E$ is potentially-throwing. +of $E$ that is not an unevaluated operand is potentially-throwing. \end{itemize} \pnum From cdaa725cce2fac8b53592ae1b842b9d1d4632e2d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:14:50 -0700 Subject: [PATCH 17/32] CWG3129 Clarify which floating-point-literals are valid --- source/lex.tex | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/lex.tex b/source/lex.tex index ef2687ddf1..9b607ab2ed 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1784,6 +1784,15 @@ else the larger or smaller representable value nearest the scaled value, chosen in an \impldef{choice of larger or smaller value of \grammarterm{floating-point-literal}} manner. +\begin{example} +The following example assumes that +\tcode{std::float32_t} is supported\iref{basic.extended.fp}. +\begin{codeblock} +std::float32_t x = 0.0f32; // value \tcode{0} is exactly representable +std::float32_t y = 0.1f32; // rounded to one of two values nearest to \tcode{0.1} +std::float32_t z = 1e1000000000f32; // either greatest finite value or positive infinity +\end{codeblock} +\end{example} \rSec2[lex.string]{String literals} From ff552851a7cfd4941213ddb0fc197a31ec5bcb58 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:36:28 -0700 Subject: [PATCH 18/32] CWG3130 Naming function members of anonymous unions --- source/classes.tex | 21 ++++++++++++++++----- source/expressions.tex | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 18afda563d..376cbbe779 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1274,7 +1274,7 @@ (including the case of a constructor with no parameters). \indextext{implicitly-declared default constructor}% If there is no user-declared constructor or constructor template for class -\tcode{X}, +\tcode{X} and \tcode{X} is not an anonymous union, a non-explicit constructor having no parameters is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared default constructor is an @@ -1503,7 +1503,8 @@ \end{example} \pnum -If the class definition does not explicitly declare a copy constructor, +If the class definition does not explicitly declare a copy constructor +and the class is not an anonymous union, a non-explicit one is declared \defnx{implicitly}{constructor!copy!implicitly declared}. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy @@ -1547,6 +1548,9 @@ a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if \begin{itemize} +\item +\tcode{X} is not an anonymous union, + \item \tcode{X} does not have a user-declared copy constructor, @@ -1742,7 +1746,8 @@ \end{note} \pnum -If the class definition does not explicitly declare a copy assignment operator, +If the class definition does not explicitly declare a copy assignment operator +and the class is not an anonymous union, one is declared \defnx{implicitly}{assignment operator!copy!implicitly declared}. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy @@ -1796,6 +1801,9 @@ move assignment operator, one will be implicitly declared as defaulted if and only if \begin{itemize} +\item +\tcode{X} is not an anonymous union, + \item \tcode{X} does not have a user-declared copy constructor, @@ -2030,7 +2038,8 @@ \indextext{generated destructor|see{destructor, default}}% \indextext{destructor!default}% If a class has no user-declared -prospective destructor, +prospective destructor +and the class is not an anonymous union, a prospective destructor is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared prospective destructor is an @@ -2043,7 +2052,8 @@ \end{codeblock} \pnum -At the end of the definition of a class, +At the end of the definition of a class +other than an anonymous union, overload resolution is performed among the prospective destructors declared in that class with an empty argument list @@ -3266,6 +3276,7 @@ an \defnx{anonymous union member}{member!anonymous union} if it is a non-static data member or an \defnx{anonymous union variable}{variable!anonymous union} otherwise. +Each object of such an unnamed type shall be such an unnamed object. \indextext{access control!anonymous \tcode{union}}% \indextext{restriction!anonymous \tcode{union}}% Each \grammarterm{member-declaration} in the \grammarterm{member-specification} diff --git a/source/expressions.tex b/source/expressions.tex index 0b12ccbe1e..4571e5f806 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1436,7 +1436,7 @@ \pnum If an \grammarterm{id-expression} $E$ denotes -a member $M$ of an anonymous union\iref{class.union.anon} $U$: +a variant member $M$ of an anonymous union\iref{class.union.anon} $U$: \begin{itemize} \item If $U$ is a non-static data member, From 57120fc65796eba7f8f617bb8b40f06482ffab67 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:45:44 -0700 Subject: [PATCH 19/32] CWG3132 Unclear disambiguation rule for condition --- source/statements.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/statements.tex b/source/statements.tex index 07760a4ed4..d0d338e930 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -35,6 +35,11 @@ \begin{bnf} \nontermdef{condition}\br expression\br + condition-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{condition-declaration}\br \opt{attribute-specifier-seq} decl-specifier-seq declarator brace-or-equal-initializer\br structured-binding-declaration initializer \end{bnf} @@ -143,7 +148,7 @@ \pnum If a \grammarterm{condition} can be syntactically resolved -as either an expression or a declaration, +as either an \grammarterm{expression} or a \grammarterm{condition-declaration}, it is interpreted as the latter. \pnum From 7a53be5bf8dc0632c597083fbc9b53438d6da3d8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:53:43 -0700 Subject: [PATCH 20/32] CWG3133 Cv-qualified types in built-in operator candidates --- source/overloading.tex | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index f6910d355b..0bde4a3a04 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -3899,7 +3899,7 @@ \pnum For every pair of types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}, where each of \tcode{\placeholder{L}} and \tcode{\placeholder{R}} is a -floating-point or promoted integral type, +cv-unqualified floating-point or promoted integral type, there exist candidate operator functions of the form \begin{codeblock} @\placeholder{LR}@ operator*(@\placeholder{L}@, @\placeholder{R}@); @@ -3921,14 +3921,14 @@ \tcode{\placeholder{R}}. \pnum -For every integral type \tcode{\placeholder{T}} +For every cv-unqualified integral type \tcode{\placeholder{T}} there exists a candidate operator function of the form \begin{codeblock} std::strong_ordering operator<=>(@\placeholder{T}@, @\placeholder{T}@); \end{codeblock} \pnum -For every pair of floating-point types +For every pair of cv-unqualified floating-point types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}, there exists a candidate operator function of the form \begin{codeblock} @@ -4005,8 +4005,9 @@ \pnum For every triple (\tcode{\placeholder{L}}, \cvqual{vq}, \tcode{\placeholder{R}}), -where \tcode{\placeholder{L}} is an arithmetic type, -and \tcode{\placeholder{R}} is a floating-point or promoted integral type, +where \tcode{\placeholder{L}} is a cv-unqualified arithmetic type +and \tcode{\placeholder{R}} is +a cv-unqualified floating-point or promoted integral type, there exist candidate operator functions of the form \begin{codeblock} @\cvqual{vq} \placeholder{L}@& operator=(@\cvqual{vq} \placeholder{L}@&, @\placeholder{R}@); @@ -4056,7 +4057,7 @@ \tcode{\placeholder{R}}), where \tcode{\placeholder{L}} -is an integral type, and +is a cv-unqualified integral type and \tcode{\placeholder{R}} is a promoted integral type, there exist candidate operator functions of the form @@ -4080,7 +4081,7 @@ \pnum For every pair of types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}, where each of \tcode{\placeholder{L}} and \tcode{\placeholder{R}} is a -floating-point or promoted integral type, +cv-unqualified floating-point or promoted integral type, there exist candidate operator functions of the form \begin{codeblock} @\placeholder{LR}@ operator?:(bool, @\placeholder{L}@, @\placeholder{R}@); From 094244c8ca41a8d982979695949decd7bc02bc6f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 16:56:48 -0700 Subject: [PATCH 21/32] CWG3136 Constant expressions of type void --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 4571e5f806..928cd5b23f 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -8849,7 +8849,7 @@ \end{itemize} or \item -a prvalue core constant expression whose result object\iref{basic.lval} +a prvalue core constant expression whose result object\iref{basic.lval} (if any) satisfies the following constraints: \begin{itemize} \item From c486843b440eb3f2e42191719adb6e8ed856430f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 17:02:26 -0700 Subject: [PATCH 22/32] CWG3142 Possible expansions of __LINE__ changing over time --- source/preprocessor.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index abf67872bd..c699b6a918 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2280,7 +2280,9 @@ \item \indextext{__line__@\mname{LINE}}% \mname{LINE}\\ -An integer literal representing the presumed line number of +\tcode{0} or a decimal integer literal\iref{lex.icon}, +with no digit separators and no \grammarterm{integer-suffix}, +representing the presumed line number of the current source line within the current source file. \begin{note} The presumed line number can be changed by the \tcode{\#line} directive\iref{cpp.line}. From 35ed3ee4f4343c970a9e87f5b90ce249b310de7c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:41:59 -0700 Subject: [PATCH 23/32] CWG3148 Definition of "user-declared" special member function --- source/classes.tex | 30 +++++++++++++++++++++++------- source/declarations.tex | 16 ++++++++-------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 376cbbe779..696977c89c 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -580,6 +580,9 @@ shall either declare at least one member name of the class or declare at least one unnamed bit-field. +A user-declared entity is +a direct member or a friend that, in either case, +is declared by a \grammarterm{member-declaration}. \pnum A \defn{data member} is either a non-function member introduced by a @@ -1273,10 +1276,12 @@ has a default argument (including the case of a constructor with no parameters). \indextext{implicitly-declared default constructor}% -If there is no user-declared constructor or constructor template for class -\tcode{X} and \tcode{X} is not an anonymous union, +If a class does not have +a user-declared constructor or constructor template, +and \tcode{X} is not an anonymous union, a non-explicit constructor having no parameters is implicitly declared as defaulted\iref{dcl.fct.def}. + An implicitly-declared default constructor is an inline public member of its class. @@ -1503,7 +1508,7 @@ \end{example} \pnum -If the class definition does not explicitly declare a copy constructor +If the class does not have a user-declared copy constructor and the class is not an anonymous union, a non-explicit one is declared \defnx{implicitly}{constructor!copy!implicitly declared}. If the class definition declares a move @@ -1544,8 +1549,8 @@ \pnum \indextext{constructor!move!implicitly declared}% -If the definition of a class \tcode{X} does not explicitly declare -a move constructor, a non-explicit one will be +If a class \tcode{X} does not have +a user-declared move constructor, a non-explicit one will be implicitly declared as defaulted if and only if \begin{itemize} \item @@ -1605,6 +1610,17 @@ an rvalue which can use the copy constructor instead. \end{note} +\pnum +\begin{note} +A using-declaration in a derived class \tcode{C} that +names a constructor from a base class +never suppresses the implicit declaration of +a copy/move constructor of \tcode{C}, +even if the base class constructor would be +a copy or move constructor +if declared as a member of \tcode{C}. +\end{note} + \pnum \indextext{constructor!copy!trivial}% \indextext{constructor!move!trivial}% @@ -1746,10 +1762,10 @@ \end{note} \pnum -If the class definition does not explicitly declare a copy assignment operator +If the class does not have a user-declared copy assignment operator and the class is not an anonymous union, one is declared \defnx{implicitly}{assignment operator!copy!implicitly declared}. -If the class definition declares a move +If the class has a user-declared move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defaulted\iref{dcl.fct.def}. diff --git a/source/declarations.tex b/source/declarations.tex index eac2152fbf..64e28e5217 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -8803,14 +8803,14 @@ \grammarterm{using-declaration} cannot refer to a destructor for a base class. \end{note} -If a constructor or assignment operator brought from a base class into a derived class -has the signature of a copy/move constructor or assignment operator -for the derived class\iref{class.copy.ctor,class.copy.assign}, -the \grammarterm{using-declaration} does not by itself -suppress the implicit declaration of the derived class member; -the member from the base class is hidden or overridden -by the implicitly-declared copy/move constructor or assignment operator -of the derived class, as described below. +\begin{note} +A \grammarterm{using-declarator} that +names a member function of a base class +does not suppress the implicit declaration of a special member function +in the derived class, +even if their signatures are the +same\iref{class.default.ctor, class.copy.ctor, class.copy.assign}. +\end{note} \pnum A \grammarterm{using-declaration} shall not name a \grammarterm{template-id}. From 8359980d67ec8d60fbf6683f54dd278b051201d3 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:44:57 -0700 Subject: [PATCH 24/32] CWG3151 Closure types that are final --- source/expressions.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 928cd5b23f..514a4a21d3 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2238,7 +2238,8 @@ \end{note} \pnum -The closure type is not an aggregate type\iref{dcl.init.aggr}; +The closure type is not an aggregate type\iref{dcl.init.aggr} +and is not \tcode{final}\iref{class.pre}; it is a structural type\iref{term.structural.type} if and only if the lambda has no \grammarterm{lambda-capture}. An implementation may define the closure type differently from what From 93bef8380a4800de397683c5555e6745728c5743 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:54:18 -0700 Subject: [PATCH 25/32] CWG3153 Immediate-escalating defaulted comparison --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 514a4a21d3..f2f91b6fbc 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -9206,7 +9206,7 @@ the call operator of a lambda that is not declared with the \keyword{consteval} specifier, \item -a defaulted special member function +a non-user-provided defaulted function that is not declared with the \keyword{consteval} specifier, or \item a function that is not a prospective destructor and From ce4ef371cca9afa3b5554d65367970ead136d50a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:02:32 -0700 Subject: [PATCH 26/32] CWG3155 Escalation of virtual functions --- source/classes.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 696977c89c..0bd09f6f32 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -4128,11 +4128,11 @@ \indextext{function!virtual|)} \pnum -A class with a \keyword{consteval} virtual function that overrides -a virtual function that is not \keyword{consteval} +A class with an immediate virtual function that overrides +a non-immediate virtual function shall have consteval-only type\iref{basic.types.general}. -A \keyword{consteval} virtual function shall not be overridden by -a virtual function that is not \keyword{consteval}. +An immediate virtual function shall not be overridden by +a non-immediate virtual function. \rSec2[class.abstract]{Abstract classes}% From d112df885500a416d028b14d50849747f6cb4e22 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:05:16 -0700 Subject: [PATCH 27/32] CWG3156 Handling of deleted functions in unevaluated lambda-captures --- source/expressions.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index f2f91b6fbc..20418dbf94 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3093,12 +3093,13 @@ \end{example} \pnum -When the \grammarterm{lambda-expression} is evaluated, the entities that are +The entities that are captured by copy are used to direct-initialize each corresponding non-static data member of the resulting closure object, and the non-static data members corresponding to the \grammarterm{init-capture}{s} are initialized as indicated by the corresponding \grammarterm{initializer} (which may be copy- or direct-initialization). (For array members, the array elements are direct-initialized in increasing subscript order.) These initializations are performed +when the \grammarterm{lambda-expression} is evaluated and in the (unspecified) order in which the non-static data members are declared. \begin{note} This ensures that the destructions will occur in the reverse order of the constructions. From 750418c18f1b53a1604ed31d39ba39fb23762c9f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:11:41 -0700 Subject: [PATCH 28/32] CWG3157 Missing handling of operator new[] for deallocation function template matching --- source/templates.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index 467b190a19..a6398e1da8 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -4404,10 +4404,10 @@ \item when the address of a function template specialization is taken; \item -when a placement operator delete that is a +when a placement deallocation function that is a function template specialization -is selected to match a placement operator new\iref{basic.stc.dynamic.deallocation,expr.new}; +is selected to match a placement allocation function\iref{basic.stc.dynamic.deallocation,expr.new}; \item when a friend function declaration\iref{temp.friend}, an explicit instantiation\iref{temp.explicit} or an explicit specialization\iref{temp.expl.spec} refers to @@ -9639,12 +9639,12 @@ for explicit instantiations\iref{temp.explicit}, explicit specializations\iref{temp.expl.spec}, and certain friend declarations\iref{temp.friend}. This is also done to determine whether a deallocation function template specialization matches a placement -\tcode{operator new}\iref{basic.stc.dynamic.deallocation,expr.new}. +allocation function\iref{basic.stc.dynamic.deallocation,expr.new}. In all these cases, \tcode{P} is the type of the function template being considered as a potential match and \tcode{A} is either the function type from the declaration or the type of the deallocation function that would match the placement -\tcode{operator new} as described in~\ref{expr.new}. The +allocation function as described in~\ref{expr.new}. The deduction is done as described in~\ref{temp.deduct.type}. \pnum From 72efcd9c292e6780dd05926288f74d51fd082939 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:19:45 -0700 Subject: [PATCH 29/32] CWG3171 Codify the strong ownership for modules Fixes NB US 17-030, FR 003-031 (C++26 CD). --- source/basic.tex | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 7c76b49ae6..f2ff4509e0 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3079,9 +3079,7 @@ \item they both declare type aliases or namespace aliases that have the same underlying entity, or \item -they both declare names with module linkage and are attached to the same module, or -\item -they both declare names with external linkage. +they both declare names with module or external linkage and are attached to the same module. \end{itemize} \begin{note} There are other circumstances in which declarations declare @@ -3098,9 +3096,11 @@ \end{note} \pnum -If two declarations of an entity are -attached to different modules, the program is ill-formed; -no diagnostic is required if neither is reachable from the other. +\begin{note} +If two declarations correspond but are +attached to different modules, the program is ill-formed +if one precedes the other\iref{basic.scope.scope}. +\end{note} \begin{example} \begin{codeblocktu}{\tcode{"decls.h"}} int f(); // \#1, attached to the global module @@ -3112,15 +3112,15 @@ #include "decls.h" export module M; export using ::f; // OK, does not declare an entity, exports \#1 -int g(); // error: matches \#2, but attached to \tcode{M} +int g(); // error: corresponds to \#2, but attached to \tcode{M} export int h(); // \#3 export int k(); // \#4 \end{codeblocktu} \begin{codeblocktu}{Other translation unit} import M; -static int h(); // error: matches \#3 -int k(); // error: matches \#4 +static int h(); // error: corresponds to \#3 +int k(); // error: corresponds to \#4 \end{codeblocktu} \end{example} As a consequence of these rules, From c9a53540221b808b76570d67c0427e8e829c5451 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:33:46 -0700 Subject: [PATCH 30/32] CWG3173 Remove misleading footnote about as-if rule --- source/basic.tex | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index f2ff4509e0..a648d0cebb 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3674,12 +3674,6 @@ \end{itemize} otherwise, they have distinct addresses and occupy disjoint bytes of storage. -\begin{footnote} -Under the ``as-if'' rule an -implementation is allowed to store two objects at the same machine address or -not store an object at all if the program cannot observe the -difference\iref{intro.execution}. -\end{footnote} \begin{example} \begin{codeblock} static const char test1 = 'x'; From 18db167fc2597ef482e4a20d7a59fecd299e0467 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 7 Apr 2026 03:46:07 -0700 Subject: [PATCH 31/32] FIXUP CWG2609: Fix index and location of definition "property of the implementation" --- source/intro.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/intro.tex b/source/intro.tex index a19f0ad556..3e24d06dce 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -339,11 +339,6 @@ \definition{implementation limit}{defns.impl.limits} restriction imposed upon programs by the implementation -\indexdefn{prop!implementation}% -\definition{property of the implementation}{defns.impl.prop} -behavior, for a well-formed program\iref{defns.well.formed} -construct and correct data, that depends on the implementation - \indexdefn{behavior!locale-specific}% \definition{locale-specific behavior}{defns.locale.specific} behavior that depends on local conventions of nationality, culture, and @@ -467,6 +462,11 @@ \end{codeblock} \end{example} +\indexdefn{property!of the implementation}% +\definition{property of the implementation}{defns.impl.prop} +behavior, for a well-formed program\iref{defns.well.formed} +construct and correct data, that depends on the implementation + \definition{referenceable type}{defns.referenceable} \indexdefn{type!referenceable}% type that is either an From 3a5222d5f106e9e0d9714111f435b14292919503 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 7 Apr 2026 03:57:28 -0700 Subject: [PATCH 32/32] FIXUP CWG2744: Add missing comma --- source/basic.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index a648d0cebb..7e7a639174 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3668,7 +3668,8 @@ exactly one is a subobject of $o$, and the subobject is of zero size, \item they are both subobjects of the same complete object, -at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, +at least one is a subobject of zero size, and +they are not of similar types\iref{conv.qual}, or \item they are both potentially non-unique objects; \end{itemize}