From 68767eaadec53b0b4c8c6a6238c251667e0fe76f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 13:43:21 -0700 Subject: [PATCH 01/31] 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..3e24d06dce 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -462,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 @@ -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 5d6e9c84ce6d80b7e82c169a643fdaa65db42567 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 14:09:47 -0700 Subject: [PATCH 02/31] CWG2744 Multiple objects of the same type at the same address --- source/basic.tex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index de215a04d4..44dee484d2 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3640,7 +3640,13 @@ 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 adcdd790be87d7563404e66718d8957cb35731d4 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 15:22:18 -0700 Subject: [PATCH 03/31] 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 44dee484d2..d87fc3eabe 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5985,6 +5985,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..89c77b0468 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 5d65e7f8cd2cd93d00b5b3918be800a19a2f815d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 15:24:16 -0700 Subject: [PATCH 04/31] 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 c2f1ab887cdf99b2a8f8eb9c2e2d5acc5d225b91 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:01:47 -0700 Subject: [PATCH 05/31] 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..9a2d9537f2 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 \grammarterm{pp-module-name} is not \tcode{;} or \tcode{[} +\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 7e8fea5253e4f761ca10f503da217d872d90ff2f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:12:50 -0700 Subject: [PATCH 06/31] 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 d87fc3eabe..50fb486f7a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5666,7 +5666,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 c3fbb89a9b3c2d385c83f7cd0ab8731cecb54428 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:16:33 -0700 Subject: [PATCH 07/31] 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 2821d9c7f8b9535b53b15eca6bca913676971122 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 16:53:58 -0700 Subject: [PATCH 08/31] 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 50fb486f7a..4efa1f3876 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 660f75c9e8c94800d62bbe3496d76e7c02c09ef1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 18:42:09 -0700 Subject: [PATCH 09/31] 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 4efa1f3876..e6a3b80d74 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 \keyword{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 c706a4ed4929291c60657141ae9a2b7c3aca75d1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:01:46 -0700 Subject: [PATCH 10/31] 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 89c77b0468..7efeffd09c 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 ff3d471bb14e28a232cc05c0919343dcedd1b141 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:09:09 -0700 Subject: [PATCH 11/31] 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 e6a3b80d74..02dfa58a78 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3851,8 +3851,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 e35e7c21ba605a52254e83739d982a838e302fd9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 19:27:26 -0700 Subject: [PATCH 12/31] 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 13209c788f84ef3322d6f36a99fac2c5f98c1e7e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 4 Apr 2026 20:28:57 -0700 Subject: [PATCH 13/31] 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 02dfa58a78..cb6c35816c 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 6181aa62b02db946f227e1f48b766da598236b0b Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 01:21:53 -0700 Subject: [PATCH 14/31] 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 9a2d9537f2..afcc57b78e 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 3dfbe43b587d28d02b482e852cf85ecd7930642c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 01:28:12 -0700 Subject: [PATCH 15/31] 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 4a2eed286208f5dc9e7504aea465b4d1af79ab77 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:07:17 -0700 Subject: [PATCH 16/31] 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 7f818adf3309fe39bf1e25fd993100a0bae1261f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:14:50 -0700 Subject: [PATCH 17/31] 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 931cad9d1575157b7262c8f3ecb6ddc4462458fa Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:36:28 -0700 Subject: [PATCH 18/31] 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 7efeffd09c..e753404960 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 29022b75083f2d5c274d4f256fb07caa4adb1061 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:45:44 -0700 Subject: [PATCH 19/31] 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 d339a26a38cf5165e4ed5fa5c0a25ce157497349 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 02:53:43 -0700 Subject: [PATCH 20/31] 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 870aab726b73f94aa22df1f4f7779cf7668a2c8f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 16:56:48 -0700 Subject: [PATCH 21/31] 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 e753404960..4fe0fb52eb 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 20e988a730acccc04319dbc1520d9601585ab439 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 17:02:26 -0700 Subject: [PATCH 22/31] 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 afcc57b78e..13c2bdfb28 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 c25b52ebbc4c1f788acc85b8e827cb61afa336ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 12 Apr 2026 00:24:39 +0100 Subject: [PATCH 23/31] [cpp.predefined] Insert "The integer literal" as introducer. This avoids starting a sentence with a symbol, and it is also consistent with other nearby descriptions. --- source/preprocessor.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 13c2bdfb28..03385c5022 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2280,7 +2280,7 @@ \item \indextext{__line__@\mname{LINE}}% \mname{LINE}\\ -\tcode{0} or a decimal integer literal\iref{lex.icon}, +The integer literal \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. From 30b9804cc7d120fff2677ed5e2ff2fa14e87b8f7 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:41:59 -0700 Subject: [PATCH 24/31] CWG3148 Definition of "user-declared" special member function Editorial note: * In new wording from previous CWG3130, which added a new reference to "X" in [class.default.ctor], change "X" to "the class", since the change from CWG3148 removes the name "X". --- 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..5045e9b65a 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -580,6 +580,10 @@ shall either declare at least one member name of the class or declare at least one unnamed bit-field. +A \defnx{user-declared}{entity!user-declared} +\indextext{user-declared entity|see{entity, 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,8 +1277,9 @@ 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 the class 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 +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 383e447e08e527981259472ca2c9d54d64203fd8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:44:57 -0700 Subject: [PATCH 25/31] 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 4fe0fb52eb..1f5af19f3d 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 e3b6062225d72ffa828140c59b99e59b75c10f80 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 21:54:18 -0700 Subject: [PATCH 26/31] 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 1f5af19f3d..eb406086c7 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 a0b9b3b67b87ddad4fed9a89701bd7504b3d4f6b Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:02:32 -0700 Subject: [PATCH 27/31] 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 5045e9b65a..5a0c0ee597 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 8c7d950a812bcaa5d7ce4cdc8091b2f11982ce3a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:05:16 -0700 Subject: [PATCH 28/31] 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 eb406086c7..4917eca901 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 9959c52d12865f31e5b7cbf9afdc3c19982cfb80 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:11:41 -0700 Subject: [PATCH 29/31] 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 9b822e32e7d1ba9cb074b8cec8b55edbaede59a4 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:19:45 -0700 Subject: [PATCH 30/31] 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 cb6c35816c..1f70a842ae 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: conflicts with \#3 +int k(); // error: conflicts with \#4 \end{codeblocktu} \end{example} As a consequence of these rules, From 30d255bd0aec5da27acbaaf1b3efffb07d8527fb Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 5 Apr 2026 22:33:46 -0700 Subject: [PATCH 31/31] 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 1f70a842ae..adb52f3b89 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3675,12 +3675,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';