diff --git a/source/basic.tex b/source/basic.tex index c1f58de60a..4ecd827d25 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -2292,11 +2292,11 @@ the innermost enclosing non-inline namespaces for its associated entities as well as every element of the inline namespace set\iref{namespace.def} of those namespaces. -Argument-dependent lookup finds -all declarations of functions and function templates that +Argument-dependent lookup for a name $N$ finds +all declarations of functions and function templates named $N$ that \begin{itemize} \item -are found by a search of any associated namespace, or +are found by a search for $N$ in any associated namespace, or \item are declared as a friend\iref{class.friend} of any class with a reachable definition in the set of associated entities, or @@ -2307,7 +2307,7 @@ have the same innermost enclosing non-inline namespace scope as a declaration of an associated entity attached to \tcode{M}\iref{basic.link}. \end{itemize} -If the lookup is for a dependent name\iref{temp.dep,temp.dep.candidate}, +If $N$ is a dependent name\iref{temp.dep,temp.dep.candidate}, the above lookup is also performed from each point in the instantiation context\iref{module.context} of the lookup, additionally ignoring any declaration that @@ -3942,7 +3942,7 @@ \item storage with the proper alignment and size for type \tcode{T} is obtained, and \item its initialization (if any) is complete - (including vacuous initialization)\iref{dcl.init}, + (including vacuous initialization)\iref{dcl.init, class.base.init}, \end{itemize} except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the @@ -6270,8 +6270,8 @@ Every integer type has an \term{integer conversion rank} defined as follows: \begin{itemize} -\item No two signed integer types other than \keyword{char} and \tcode{\keyword{signed} -\keyword{char}} (if \keyword{char} is signed) have the same rank, even if they have +\item No two signed integer types +have the same rank, even if they have the same representation. \item The rank of a signed integer type is greater than the rank @@ -6289,18 +6289,12 @@ \item The rank of any standard integer type is greater than the rank of any extended integer type with the same width. -\item The rank of \keyword{char} equals the rank of \tcode{\keyword{signed} \keyword{char}} -and \tcode{\keyword{unsigned} \keyword{char}}. - \item The rank of \tcode{bool} is less than the rank of all -standard integer types. +other integer types. \item -\indextext{type!\idxcode{wchar_t}}% -\indextext{type!\idxcode{char16_t}}% -\indextext{type!\idxcode{char32_t}}% -The ranks of \keyword{char8_t}, \keyword{char16_t}, \keyword{char32_t}, and -\keyword{wchar_t} equal the ranks of their underlying +The ranks of the character types +equal the ranks of their corresponding underlying types\iref{basic.fundamental}. \item The rank of any extended signed integer type relative to another @@ -6719,6 +6713,9 @@ of subexpressions of individual expressions that are otherwise either unsequenced or indeterminately sequenced are evaluated in lexical order. +For a function call\iref{expr.call}, +any default arguments used are evaluated in the order as if +an argument were present for the corresponding parameter. \rSec2[intro.multithread]{Multi-threaded executions and data races} @@ -7618,6 +7615,7 @@ the initialization associated with the entity for thread \placeholder{t} is sequenced before the first non-initialization odr-use by \placeholder{t} of any non-inline variable with thread storage duration +and dynamic initialization defined in the same translation unit as the variable to be initialized. It is \impldef{threads and program points at which deferred dynamic initialization is performed} in which threads and at which points in the program such deferred dynamic initialization occurs. diff --git a/source/classes.tex b/source/classes.tex index 6cd80b2796..c8aa78a14b 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -5621,8 +5621,6 @@ class, thus its constructors never initialize virtual base classes, therefore the corresponding \grammarterm{mem-initializer}{s} can be omitted. \end{note} -An attempt to initialize more than one non-static data member of a union renders the -program ill-formed. \indextext{initialization!const member}% \indextext{initialization!reference member}% \begin{note} @@ -5658,6 +5656,18 @@ \end{codeblock} \end{example} +\pnum +An attempt to initialize more than one non-static data member of a union renders the +program ill-formed. + +\pnum +An object's initialization is considered complete when +a non-delegating constructor for that object returns. +\begin{note} +Therefore, an object's lifetime can begin\iref{basic.life} +before all delegating constructors have completed. +\end{note} + \pnum If a given non-static data member has both a default member initializer and a \grammarterm{mem-initializer}, the initialization specified by the @@ -6073,7 +6083,7 @@ \end{example} \pnum -During the construction of an object, +During the initialization of an object, if the value of any of its subobjects or any element of its object representation is accessed through a glvalue that is not obtained, directly or indirectly, from diff --git a/source/compatibility.tex b/source/compatibility.tex index 7f97796edc..18f307cdd2 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -547,6 +547,35 @@ \end{codeblock} \end{example} +\rSec2[diff.cpp20.over]{\ref{over}: overloading} + +\diffref{over.match.class.deduct} +\change +Deducing class template arguments from inherited constructors. +\rationale +Making class template argument deduction consistent with construction. +\effect +Valid ISO \CppXX{} code may become ill-formed or change meaning +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +template +struct B { + B(T); +}; + +template +struct D : B { + D(T); + using B::B; + T m = "a"; // \#1 +}; + +D d(""); // ill-formed at \#1 (\tcode{T} deduced as \tcode{const char}); + // previously well-formed (\tcode{T} deduced as \tcode{const char*}) +\end{codeblock} +\end{example} + \rSec2[diff.cpp20.temp]{\ref{temp}: templates} \diffref{temp.deduct.type} @@ -2992,6 +3021,43 @@ \howwide Uncommon. +\diffref{expr.arith.conv} +\change +The usual arithmetic conversions differ, between C and \Cpp{}, +in the treatment of enumeration types with no fixed underlying type. +In \Cpp{}, values of such types are not specified +as converting to the underlying type of the enumeration +as part of the usual arithmetic conversions. +Instead, integral promotions\iref{conv.prom} +based on the values of the enumeration\iref{dcl.enum} are applied. +\rationale +Avoids the difference that can arise in C +when replacing an enumeration constant in +an expression with a cast of the same enumeration constant +to the enumeration type. +Allows \Cpp{} to treat an enumerator with behavior +like that of \keyword{int} +even while giving the enumerator the type of its enumeration. +\effect +Changes to semantics of well-defined feature. +Some C expressions that have a dependence upon +the implementation-defined +underlying type of affected enumeration types +will yield different results +(as they would if a different underlying type +is chosen by the C implementation). +\begin{example} +\begin{codeblock} +typedef enum { E0 } E; // the underlying type of \tcode{E} can be \tcode{unsigned int} +static_assert(((E)E0 - 1 < 0) == (E0 - 1 < 0), "Must pass for C++"); +\end{codeblock} +The \tcode{static_assert} may fail in C. +\end{example} +\difficulty +Programs must add explicit casts to the underlying type. +\howwide +Rare. + \diffref{expr.post.incr,expr.pre.incr} \change Decrement operator is not allowed with \keyword{bool} operand. diff --git a/source/declarations.tex b/source/declarations.tex index 627360a226..81750ffb34 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1911,9 +1911,9 @@ A placeholder type can also be used in the \grammarterm{type-specifier-seq} of the \grammarterm{new-type-id} or -in the \grammarterm{type-id} of a +in the \grammarterm{nofun-type-id} of a \grammarterm{new-expression}\iref{expr.new}. -In such a \grammarterm{type-id}, +In such a \grammarterm{nofun-type-id}, the placeholder type shall appear as one of the \grammarterm{type-specifier}{s} in the \grammarterm{type-specifier-seq} or @@ -2288,7 +2288,7 @@ A placeholder for a deduced class type can also be used in the \grammarterm{type-specifier-seq} -in the \grammarterm{new-type-id} or \grammarterm{type-id} +in the \grammarterm{new-type-id} or \grammarterm{nofun-type-id} of a \grammarterm{new-expression}\iref{expr.new}, as the \grammarterm{simple-type-specifier} in an explicit type conversion (functional notation)\iref{expr.type.conv}, @@ -2464,9 +2464,16 @@ \end{note} \pnum -The optional \grammarterm{requires-clause} in an +The \grammarterm{initializer} of an \grammarterm{init-declarator} +shall not be present unless +the declarator declares a variable and +the host scope\iref{basic.scope.scope} of the declaration +is the same as its target scope. + +\pnum +The optional \grammarterm{requires-clause} of an \grammarterm{init-declarator} or \grammarterm{member-declarator} -shall be present only if the declarator declares a +shall not be present unlesss the declarator declares a templated function\iref{temp.pre}. % \indextext{trailing requires-clause@trailing \gterm{requires-clause}|see{\gterm{requires-clause}, trailing}}% @@ -2494,8 +2501,8 @@ \pnum The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func} -in an \grammarterm{init-declarator} -shall be present only if +of an \grammarterm{init-declarator} +shall not be present unless the \grammarterm{declarator} declares a function. \pnum @@ -2529,7 +2536,7 @@ \begin{bnf} \nontermdef{trailing-return-type}\br - \terminal{->} type-id + \terminal{->} nofun-type-id \end{bnf} \begin{bnf} @@ -2567,20 +2574,40 @@ \pnum \indextext{type name}% -To specify type conversions explicitly, \indextext{operator!cast}% -and as an argument of -\tcode{sizeof}, -\tcode{alignof}, -\keyword{new}, -or -\tcode{typeid}, -the name of a type shall be specified. -This can be done with a -\grammarterm{type-id} or \grammarterm{new-type-id}\iref{expr.new}, -which is syntactically a declaration for a variable or function +A type can be named with a +\grammarterm{type-id}, +\grammarterm{nofun-type-id}, or +\grammarterm{new-type-id}\iref{expr.new}, +each of +which is syntactically a declaration for a variable or +(only for a \grammarterm{type-id}) function of that type that omits the name of the entity. +\begin{bnf} +\nontermdef{nofun-type-id}\br + type-specifier-seq \opt{nofun-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{nofun-declarator}\br + ptr-nofun-declarator\br + noptr-nofun-declarator parameters-and-qualifiers trailing-return-type +\end{bnf} + +\begin{bnf} +\nontermdef{ptr-nofun-declarator}\br + noptr-nofun-declarator\br + ptr-operator \opt{ptr-nofun-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{noptr-nofun-declarator}\br + noptr-nofun-declarator parameters-and-qualifiers\br + \opt{noptr-nofun-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-nofun-declarator \terminal{)} +\end{bnf} + \begin{bnf} \nontermdef{type-id}\br type-specifier-seq \opt{abstract-declarator} @@ -2625,6 +2652,7 @@ It is possible to identify uniquely the location in the \grammarterm{abstract-declarator} +or \grammarterm{nofun-declarator} where the identifier would appear if the construction were a declarator in a declaration. The named type is then the same as the type of the @@ -2716,6 +2744,10 @@ \grammarterm{type-id} in its syntactic context shall be considered a \grammarterm{type-id}. +\begin{note} +No such ambiguity can arise between an expression and +a \grammarterm{nofun-type-id}. +\end{note} However, a construct that can syntactically be a \grammarterm{type-id} whose outermost \grammarterm{abstract-declarator} would match the grammar of an \grammarterm{abstract-declarator} @@ -2731,19 +2763,18 @@ Y d; // expression void foo(signed char a) { - sizeof(int()); // \grammarterm{type-id} (ill-formed) + sizeof(int()); // expression sizeof(int(a)); // expression - sizeof(int(unsigned(a))); // \grammarterm{type-id} (ill-formed) - - (int())+1; // \grammarterm{type-id} (ill-formed) + sizeof(int(unsigned(a))); // expression + (int())+1; // expression (int(a))+1; // expression - (int(unsigned(a)))+1; // \grammarterm{type-id} (ill-formed) + (int(unsigned(a)))+1; // expression } typedef struct BB { int C[2]; } *B, C; void g() { sizeof(B()->C[1]); // OK, \tcode{\keyword{sizeof}(}expression\tcode{)} - sizeof(auto()->C[1]); // error: \keyword{sizeof} of a function returning an array + sizeof(auto()->C[1]); // error: ill-formed expression } \end{codeblock} \end{example} @@ -3791,13 +3822,30 @@ If the \grammarterm{parameter-declaration-clause} is empty, the function takes no arguments. -A parameter list consisting of a single unnamed non-object parameter of -non-dependent type \keyword{void} is equivalent to an empty parameter -list. +A parameter list consisting of a single unnamed non-object parameter +whose type is the same as\iref{temp.over.link} \keyword{void} +is interpreted as an empty parameter list. \indextext{parameter!\idxcode{void}}% Except for this special case, a parameter shall not have type \cv{}~\keyword{void}. A parameter with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. + +\begin{example} +\begin{codeblock} +template +struct S { + void f(std::void_t); // \#1 +}; +S x; // error: \#1 has a parameter of type \tcode{void} + +template +struct S2 { + void f(std::void_t); // \#2 +}; +S2 y; // OK, \#2 is a zero-parameter function +\end{codeblock} +\end{example} + If the \grammarterm{parameter-declaration-clause} \indextext{argument type!unknown}% @@ -5012,11 +5060,6 @@ and~\ref{stmt.dcl}. \end{note} -\pnum -A declaration $D$ of a variable with linkage -shall not have an \grammarterm{initializer} -if $D$ inhabits a block scope. - \pnum \indextext{initialization!default}% \indextext{variable!indeterminate uninitialized}% @@ -6683,6 +6726,11 @@ given \grammarterm{initializer-clause} is sequenced before every value computation and side effect associated with any \grammarterm{initializer-clause} that follows it in the comma-separated list of the \grammarterm{initializer-list}. +If the \grammarterm{initializer-clause}{s} of +the \grammarterm{initializer-list} +are interpreted as arguments of a constructor call\iref{over.match.list}, +any default arguments used are evaluated in the order as if +an \grammarterm{initializer-clause} were present for the corresponding parameter. \begin{note} This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the @@ -6690,6 +6738,22 @@ call, even though ordinarily there are no sequencing constraints on the arguments of a call. \end{note} +\begin{example} +\begin{codeblock} +#include +struct I { + I(int x) { std::cout << x; } +}; +struct S { + S(I, I = 2) {} +}; +int main() { + S(1, 2); std::cout << '\n'; // unspecified order; prints \tcode{12} or \tcode{21} + S{1, 2}; std::cout << '\n'; // prints \tcode{12} + S{1}; // prints \tcode{12} +} +\end{codeblock} +\end{example} \pnum An object of type \tcode{std::initializer_list} is constructed from @@ -8059,7 +8123,8 @@ \pnum Two enumeration types are \defnx{layout-compatible enumerations}{layout-compatible!enumeration} -if they have the same underlying type. +if they have the same underlying type +and the same values. \pnum The value of an enumerator or an object of an unscoped enumeration type is @@ -9405,7 +9470,7 @@ \begin{bnf} \nontermdef{alignment-specifier}\br - \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br + \keyword{alignas} \terminal{(} nofun-type-id \opt{\terminal{...}} \terminal{)}\br \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)} \end{bnf} @@ -9637,8 +9702,8 @@ \pnum An \grammarterm{alignment-specifier} of the form -\tcode{alignas(} \grammarterm{type-id} \tcode{)} has the same -effect as \tcode{alignas(\brk{}alignof(} \grammarterm{type-id}~\tcode{))}\iref{expr.alignof}. +\tcode{alignas(} \grammarterm{nofun-type-id} \tcode{)} has the same +effect as \tcode{alignas(alignof(} \grammarterm{nofun-type-id}~\tcode{))}\iref{expr.alignof}. \pnum The alignment requirement of an entity is the strictest nonzero alignment diff --git a/source/expressions.tex b/source/expressions.tex index 72f77d87bb..8fb154459b 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3934,7 +3934,7 @@ \indextext{evaluation!unspecified order of function call}% \indextext{evaluation!unspecified order of argument}% The \grammarterm{postfix-expression} is sequenced before -each \grammarterm{expression} in the \grammarterm{expression-list} +each \grammarterm{initializer-clause} in the \grammarterm{expression-list} and any default argument. The initialization of a parameter or, if the implementation introduces any temporary objects @@ -5226,9 +5226,9 @@ \terminal{--} cast-expression\br await-expression\br \keyword{sizeof} unary-expression\br - \keyword{sizeof} \terminal{(} type-id \terminal{)}\br + \keyword{sizeof} \terminal{(} nofun-type-id \terminal{)}\br \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br - \keyword{alignof} \terminal{(} type-id \terminal{)}\br + \keyword{alignof} \terminal{(} nofun-type-id \terminal{)}\br noexcept-expression\br new-expression\br delete-expression\br @@ -5656,7 +5656,7 @@ occupied by a non-potentially-overlapping object of the type of its operand. The operand is either an expression, which is an unevaluated operand\iref{term.unevaluated.operand}, or a parenthesized -\grammarterm{type-id}. +\grammarterm{nofun-type-id}. \indextext{type!incomplete}% The \keyword{sizeof} operator shall not be applied to an expression that has function or incomplete type, @@ -5747,7 +5747,7 @@ \indextext{\idxcode{alignof}}% \indextext{expression!\idxcode{alignof}}% An \keyword{alignof} expression yields the alignment requirement -of its operand type. The operand shall be a \grammarterm{type-id} +of its operand type. The operand shall be a \grammarterm{nofun-type-id} representing a complete object type, or an array thereof, or a reference to one of those types. @@ -5805,7 +5805,7 @@ \indextext{storage management|see{\tcode{delete}}}% \indextext{\idxcode{new}}% The \grammarterm{new-expression} attempts to create an object of the -\grammarterm{type-id} or \grammarterm{new-type-id}\iref{dcl.name} to which +\grammarterm{nofun-type-id} or \grammarterm{new-type-id}\iref{dcl.name} to which it is applied. The type of that object is the \defnadj{allocated}{type}. \indextext{type!incomplete}% This type shall be a complete object type\iref{term.incomplete.type}, @@ -5816,14 +5816,14 @@ \grammarterm{new-expression}{s}. \end{note} \begin{note} -The \grammarterm{type-id} can be a cv-qualified type, in which case the +The \grammarterm{nofun-type-id} can be a cv-qualified type, in which case the object created by the \grammarterm{new-expression} has a cv-qualified type. \end{note} \begin{bnf} \nontermdef{new-expression}\br \opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer} \br - \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer} + \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} nofun-type-id \terminal{)} \opt{new-initializer} \end{bnf} \indextext{\idxcode{new}!storage allocation}% @@ -5861,12 +5861,12 @@ a placeholder for a deduced class type\iref{dcl.type.class.deduct} appears in the \grammarterm{type-specifier-seq} of a \grammarterm{new-type-id} or -\grammarterm{type-id} of a \grammarterm{new-expression}, +\grammarterm{nofun-type-id} of a \grammarterm{new-expression}, the allocated type is deduced as follows: Let \placeholder{init} be the \grammarterm{new-initializer}, if any, and -\tcode{T} be the \grammarterm{new-type-id} or \grammarterm{type-id} of +\tcode{T} be the \grammarterm{new-type-id} or \grammarterm{nofun-type-id} of the \grammarterm{new-expression}, then the allocated type is the type deduced for the variable \tcode{x} in the invented declaration\iref{dcl.spec.auto}: @@ -5953,7 +5953,7 @@ \end{example} \pnum -If the \grammarterm{type-id} or \grammarterm{new-type-id} +If the \grammarterm{nofun-type-id} or \grammarterm{new-type-id} denotes an array type of unknown bound\iref{dcl.array}, the \grammarterm{new-initializer} shall not be omitted; the allocated object is an array with \tcode{n} elements, @@ -6053,7 +6053,7 @@ \indextext{array!\idxcode{new}}% When the allocated type is ``array of \tcode{N} \tcode{T}'' (that is, the \grammarterm{noptr-new-declarator} syntax is used or the -\grammarterm{new-type-id} or \grammarterm{type-id} denotes an array type), +\grammarterm{new-type-id} or \grammarterm{nofun-type-id} denotes an array type), the \grammarterm{new-expression} yields a prvalue of type ``pointer to \tcode{T}'' that points to the initial element (if any) of the array. Otherwise, let \tcode{T} be the allocated type; @@ -6836,7 +6836,8 @@ \end{example} \item Otherwise, if lookup finds a namespace alias\iref{namespace.alias}, -$R$ represents that namespace alias. +all declarations found by name lookup shall have the same target scope, and +$R$ represents the namespace alias. \item Otherwise, if lookup finds a namespace\iref{basic.namespace}, $R$ represents that namespace. @@ -6872,11 +6873,32 @@ Lookup never finds a partial or explicit specialization. \end{note} \end{itemize} + +\item +Otherwise, if lookup finds a type alias: +\begin{itemize} +\item +If any declaration found by name lookup is of a template parameter $T$, +$R$ represents the underlying entity of $T$. \item -Otherwise, if lookup finds a type alias $A$, -$R$ represents the underlying entity of $A$ -if $A$ was introduced by the declaration of a template parameter; -otherwise, $R$ represents $A$. +Otherwise, +all declarations found by name lookup shall have the same target scope, and +$R$ represents the type alias. +\end{itemize} +\begin{example} +\begin{codeblock} +namespace A { + using T = int; +} +namespace B { + using T = int; +} +using namespace A; +using namespace B; +auto r = ^^T; // error: lookup finds type aliases with different target scopes +\end{codeblock} +\end{example} + \item Otherwise, if lookup finds a class or an enumeration, $R$ represents the denoted type. @@ -6930,9 +6952,11 @@ then $R$ is ill-formed. \item Otherwise, if the \grammarterm{id-expression} denotes an overload set $S$, -overload resolution for the expression \tcode{\&S} with no target -shall select a unique function\iref{over.over}; -$R$ represents that function. +the expression \tcode{\& grammarterm{id-expression}} shall be well-formed +when considered as an unevaluated operand, +except that the function $F$ selected as described in \ref{over.over} +may be deleted\iref{dcl.fct.def.delete}; +$R$ represents $F$. \item Otherwise, if the \grammarterm{id-expression} denotes a variable, structured binding, enumerator, or non-static data member, @@ -6996,7 +7020,7 @@ \begin{bnf} \nontermdef{cast-expression}\br unary-expression\br - \terminal{(} type-id \terminal{)} cast-expression + \terminal{(} nofun-type-id \terminal{)} cast-expression \end{bnf} \pnum @@ -7270,8 +7294,8 @@ \item \indextext{arithmetic!pointer}% -both operands are pointers to cv-qualified or cv-unqualified -versions of the same completely-defined object type; or +both operands are pointers +to similar\iref{conv.qual} complete object types; or \item the left operand is a pointer to a completely-defined object type and the right operand has integral type. diff --git a/source/lex.tex b/source/lex.tex index bfd55be51d..a623204b69 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -650,14 +650,22 @@ a \grammarterm{header-name}\iref{lex.header} is only formed \begin{itemize} \item -immediately after the \tcode{include}, \tcode{embed}, or \tcode{import} preprocessing token in a -\tcode{\#include}\iref{cpp.include}, \tcode{\#embed}\iref{cpp.embed}, or -\tcode{import}\iref{cpp.import} directive, respectively, or +immediately after the \tcode{include} or \tcode{embed} preprocessing token in a +\tcode{\#include}\iref{cpp.include} or \tcode{\#embed}\iref{cpp.embed} +directive, respectively, or +\item +immediately after an import preprocessing token that +is at the start of a logical source line, or \item immediately after a preprocessing token sequence of \xname{has_include} or \xname{has_embed} immediately followed by \tcode{(} in a \tcode{\#if}, \tcode{\#elif}, or \tcode{\#embed} directive\iref{cpp.cond,cpp.embed}. \end{itemize} +A preprocessing token is considered to be +\defnx{immediately after}{token!immediately after} +another preprocessing token if +the preprocessing tokens are on the same logical source line and +there are no intervening preprocessing tokens. \end{itemize} \end{itemize} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 0bfb7f194f..6de526385f 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2310,46 +2310,6 @@ \tcode{operator new(std::size_t, std::align_val_t)}, etc.\iref{expr.new}. \end{note} -\item -\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT16_T}}% -\mname{STDCPP_FLOAT16_T}\\ -Defined as the integer literal \tcode{1} -if and only if the implementation supports -the \IsoFloatUndated{} floating-point interchange format binary16 -as an extended floating-point type\iref{basic.extended.fp}. - -\item -\indextext{__stdcpp_float32_t__@\mname{STDCPP_FLOAT32_T}}% -\mname{STDCPP_FLOAT32_T}\\ -Defined as the integer literal \tcode{1} -if and only if the implementation supports -the \IsoFloatUndated{} floating-point interchange format binary32 -as an extended floating-point type. - -\item -\indextext{__stdcpp_float64_t__@\mname{STDCPP_FLOAT64_T}}% -\mname{STDCPP_FLOAT64_T}\\ -Defined as the integer literal \tcode{1} -if and only if the implementation supports -the \IsoFloatUndated{} floating-point interchange format binary64 -as an extended floating-point type. - -\item -\indextext{__stdcpp_float128_t__@\mname{STDCPP_FLOAT128_T}}% -\mname{STDCPP_FLOAT128_T}\\ -Defined as the integer literal \tcode{1} -if and only if the implementation supports -the \IsoFloatUndated{} floating-point interchange format binary128 -as an extended floating-point type. - -\item -\indextext{__stdcpp_bfloat16_t__@\mname{STDCPP_BFLOAT16_T}}% -\mname{STDCPP_BFLOAT16_T}\\ -Defined as the integer literal \tcode{1} -if and only if the implementation supports an extended floating-point type -with the properties of the \grammarterm{typedef-name} \tcode{std::bfloat16_t} -as described in \ref{basic.extended.fp}. - \item \indextext{__time__@\mname{TIME}}% \mname{TIME}\\ @@ -2457,6 +2417,46 @@ The following macro names are conditionally defined by the implementation: \begin{description} +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT16_T}}% +\mname{STDCPP_FLOAT16_T}\\ +Defined, and has the value integer literal \tcode{1} +if and only if the implementation supports +the \IsoFloatUndated{} floating-point interchange format binary16 +as an extended floating-point type\iref{basic.extended.fp}. + +\item +\indextext{__stdcpp_float32_t__@\mname{STDCPP_FLOAT32_T}}% +\mname{STDCPP_FLOAT32_T}\\ +Defined, and has the value integer literal \tcode{1} +if and only if the implementation supports +the \IsoFloatUndated{} floating-point interchange format binary32 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float64_t__@\mname{STDCPP_FLOAT64_T}}% +\mname{STDCPP_FLOAT64_T}\\ +Defined, and has the value integer literal \tcode{1} +if and only if the implementation supports +the \IsoFloatUndated{} floating-point interchange format binary64 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float128_t__@\mname{STDCPP_FLOAT128_T}}% +\mname{STDCPP_FLOAT128_T}\\ +Defined, and has the value integer literal \tcode{1} +if and only if the implementation supports +the \IsoFloatUndated{} floating-point interchange format binary128 +as an extended floating-point type. + +\item +\indextext{__stdcpp_bfloat16_t__@\mname{STDCPP_BFLOAT16_T}}% +\mname{STDCPP_BFLOAT16_T}\\ +Defined, and has the value integer literal \tcode{1} +if and only if the implementation supports an extended floating-point type +with the properties of the \grammarterm{typedef-name} \tcode{std::bfloat16_t} +as described in \ref{basic.extended.fp}. + \item \indextext{__stdc__@\mname{STDC}}% \mname{STDC}\\ diff --git a/source/templates.tex b/source/templates.tex index 369755465d..5730e6598e 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2651,14 +2651,16 @@ For a type template parameter pack \tcode{T}, \tcode{T...[}\grammarterm{constant-expression}\tcode{]} denotes a unique dependent type. - -\pnum -If the \grammarterm{constant-expression} of a \grammarterm{pack-index-specifier} -is value-dependent, -two such \grammarterm{pack-index-specifier}s refer to the same type -only if their \grammarterm{constant-expression}s are equivalent\iref{temp.over.link}. -Otherwise, two such \grammarterm{pack-index-specifier}s refer to the same type -only if their indexes have the same value. +Two such \grammarterm{pack-index-specifier}s refer to the same type +only if +\begin{itemize} +\item +their \grammarterm{typedef-name}{s} refer to the same template parameter pack and +\item +if neither of their \grammarterm{constant-expression}{s} is value-dependent, then +they have the same value, otherwise +their \grammarterm{constant-expression}s are equivalent\iref{temp.over.link}. +\end{itemize} \rSec1[temp.decls]{Template declarations} @@ -5834,6 +5836,7 @@ Expressions of the following forms are type-dependent only if the type specified by the \grammarterm{type-id}, +\grammarterm{nofun-type-id}, \grammarterm{simple-type-specifier}, \grammarterm{typename-specifier}, or @@ -5846,12 +5849,12 @@ typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br typename-specifier braced-init-list\br \opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer}\br -\opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer}\br +\opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} nofun-type-id \terminal{)} \opt{new-initializer}\br \keyword{dynamic_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{static_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{const_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{reinterpret_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br -\terminal{(} type-id \terminal{)} cast-expression +\terminal{(} nofun-type-id \terminal{)} cast-expression \end{ncsimplebnf} \pnum @@ -5861,9 +5864,9 @@ \begin{ncsimplebnf} literal\br \keyword{sizeof} unary-expression\br -\keyword{sizeof} \terminal{(} type-id \terminal{)}\br +\keyword{sizeof} \terminal{(} nofun-type-id \terminal{)}\br \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br -\keyword{alignof} \terminal{(} type-id \terminal{)}\br +\keyword{alignof} \terminal{(} nofun-type-id \terminal{)}\br \keyword{typeid} \terminal{(} expression \terminal{)}\br \keyword{typeid} \terminal{(} type-id \terminal{)}\br \opt{\terminal{::}} \keyword{delete} cast-expression\br @@ -5967,14 +5970,15 @@ \grammarterm{unary-expression} or \grammarterm{expression} is type-dependent or the \grammarterm{type-id} +or \grammarterm{nofun-type-id} is dependent: \begin{ncsimplebnf} \keyword{sizeof} unary-expression\br -\keyword{sizeof} \terminal{(} type-id \terminal{)}\br +\keyword{sizeof} \terminal{(} nofun-type-id \terminal{)}\br \keyword{typeid} \terminal{(} expression \terminal{)}\br \keyword{typeid} \terminal{(} type-id \terminal{)}\br -\keyword{alignof} \terminal{(} type-id \terminal{)} +\keyword{alignof} \terminal{(} nofun-type-id \terminal{)} \end{ncsimplebnf} \begin{note} @@ -5985,6 +5989,7 @@ \pnum Expressions of the following form are value-dependent if either the \grammarterm{type-id}, +\grammarterm{nofun-type-id}, \grammarterm{simple-type-specifier}, or \grammarterm{typename-specifier} is dependent or the @@ -6006,7 +6011,7 @@ \keyword{const_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{reinterpret_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{dynamic_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br -\terminal{(} type-id \terminal{)} cast-expression +\terminal{(} nofun-type-id \terminal{)} cast-expression \end{ncsimplebnf} \pnum @@ -6807,6 +6812,27 @@ \end{codeblock} \end{example} +\pnum +Similarly, +the existence of a definition of a variable or function +is considered to affect the semantics of the program +if the instantiation is necessary to +determine the type of an expression in the program, +even if the variable or function is not odr-used\iref{basic.def.odr}. +\begin{example} +\begin{codeblock} +template struct X { + static inline int arr[] = {1, 2, T::error}; +}; +decltype(+X::arr) r; // error: definition of \tcode{X::arr} is instantiated to complete its type + +template struct X2 { + static inline int arr[3] = {1, 2, T::error}; +}; +decltype(+X2::arr) r2; // OK, type of \tcode{arr} is complete and arr is not odr-used +\end{codeblock} +\end{example} + \pnum If the function selected by overload resolution\iref{over.match} can be determined without instantiating a class template definition, @@ -8280,10 +8306,9 @@ or $\tcode{P}'\tcode{[N]}$ for some $\tcode{P}'$ and \tcode{N} and the argument is a non-empty initializer list\iref{dcl.init.list}, then deduction is -performed instead for each element of the initializer list independently, -taking $\tcode{P}'$ -as separate function template parameter types $\tcode{P}'_i$ -and the $i^\text{th}$ initializer element as the corresponding argument. +instead performed as if +each element of the initializer list were the argument +for a separate parameter having type $\tcode{P}'$. In the $\tcode{P}'\tcode{[N]}$ case, if \tcode{N} is a constant template parameter, \tcode{N} is deduced from the length of the initializer list. Otherwise, an initializer list argument causes the @@ -9010,7 +9035,7 @@ \item The \grammarterm{nested-name-specifier} -of a type that was specified using a +of a type or template that was specified using a \grammarterm{qualified-id}. \item A \grammarterm{pack-index-specifier} or a \grammarterm{pack-index-expression}.