diff --git a/source/basic.tex b/source/basic.tex index 78a03978cd..881659468a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -954,7 +954,8 @@ declaration, \grammarterm{parameter-declaration-clause}, \grammarterm{statement}, -\grammarterm{handler}, or +\grammarterm{handler}, +\grammarterm{lambda-expression}, or contract assertion (as described in the following subclauses of \ref{basic.scope}) appearing in another scope, which thereby contains $S$. @@ -2887,8 +2888,8 @@ \indextext{program}% \indextext{linking}% A \defn{program} consists of one or more translation units\iref{lex.phases} -linked together. A translation unit consists -of a sequence of declarations. +that are translated and linked together. +A translation unit consists of a sequence of declarations. \begin{bnf} \nontermdef{translation-unit}\br @@ -3477,7 +3478,7 @@ An object that is not a subobject of any other object is called a \defn{complete object}. If an object is created -in storage associated with a member subobject or array element \placeholder{e} +in storage associated with a subobject \placeholder{e} (which may or may not be within its lifetime), the created object is a subobject of \placeholder{e}'s containing object if @@ -3487,8 +3488,12 @@ \item the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and \item +\placeholder{e} is not a potentially-overlapping subobject, and +\item the new object is of the same type as \placeholder{e} (ignoring cv-qualification). \end{itemize} +In this case, \placeholder{e} and the created object are +\defnadj{corresponding direct}{subobjects}{subobject}. \pnum \indextext{object!providing storage for}% @@ -4013,22 +4018,24 @@ \end{note} \pnum -An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if +An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if either +\begin{itemize} +\item +$o_1$ and $o_2$ are complete objects for which: \begin{itemize} +\item $o_1$ is not const, \item the storage that $o_2$ occupies exactly overlays the storage that $o_1$ occupied, and - \item $o_1$ and $o_2$ are of the same type -(ignoring the top-level cv-qualifiers), and - -\item $o_1$ is not a const, complete object, and - -\item neither $o_1$ nor $o_2$ -is a potentially-overlapping subobject\iref{intro.object}, and +(ignoring the top-level cv-qualifiers), or +\end{itemize} -\item either $o_1$ and $o_2$ are both complete objects, or -$o_1$ and $o_2$ are direct subobjects of objects $p_1$ and $p_2$, respectively, -and $p_1$ is transparently replaceable by $p_2$. +\item +$o_1$ and $o_2$ are corresponding direct subobjects\iref{intro.object} for which: +\begin{itemize} +\item the complete object of $o_1$ is not const or +\item $o_1$ is a mutable member subobject or subobject thereof. +\end{itemize} \end{itemize} \pnum @@ -4813,7 +4820,9 @@ \item a class member access\iref{expr.ref} using the \tcode{.} operator where the left operand is one of these expressions and - the right operand designates a non-static data member of non-reference type, + the right operand designates + a non-static data member\iref{class.mem.general} of non-reference type or + a direct base class relationship\iref{class.derived.general}, \item a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator where the left operand is one of these expressions and @@ -4831,6 +4840,15 @@ to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof, +\item + an explicit type conversion (functional notation)\iref{expr.type.conv} + to a reference type whose initializer is a \grammarterm{braced-init-list} + where the reference is + \begin{itemize} + \item bound directly to the glvalue result of one of these expressions + (necessarily the sole element of the \grammarterm{braced-init-list}) or + \item bound to the result of a temporary materialization conversion, + \end{itemize} \item a conditional expression\iref{expr.cond} that is a glvalue where the second or third operand is one of these expressions, or @@ -5593,13 +5611,15 @@ is an incomplete type that cannot be completed; such a type has an empty set of values. It is used as the return type for functions that do not return a value. -An expression of type \cv{}~\keyword{void} shall -be used only as +\begin{note} +An expression of type \cv{}~\keyword{void} can be used as \begin{itemize} \item an expression statement\iref{stmt.expr}, \item the expression in a \keyword{return} statement\iref{stmt.return} for a function with the return type \cv{}~\keyword{void}, \item an operand of a comma expression\iref{expr.comma}, +\item the operand of a parenthesized expression\iref{expr.prim.paren}, +\item a requirement in a \keyword{requires} expression\iref{expr.prim.req.general}, \item the second or third operand of \tcode{?:}\iref{expr.cond}, \item the operand of a \keyword{typeid} expression\iref{expr.typeid}, \item the operand of a \keyword{noexcept} operator\iref{expr.unary.noexcept}, @@ -5607,6 +5627,7 @@ \item the operand of an explicit conversion to type \cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. \end{itemize} +\end{note} \pnum The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. @@ -7171,8 +7192,13 @@ \indextext{\idxcode{main} function!implementation-defined parameters to}% An implementation shall allow both \begin{itemize} -\item a function of \tcode{()} returning \keyword{int} and -\item a function of \tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} returning \keyword{int} +\item +an ``optionally \tcode{noexcept} function of +\tcode{()} returning \keyword{int}'' and +\item +an ``optionally \tcode{noexcept} function of +\tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} +returning \keyword{int}'' \end{itemize} \indextext{\idxcode{argc}}% \indextext{\idxcode{argv}}% @@ -7490,7 +7516,7 @@ \indextext{program!termination|(}% \indextext{object!destructor static}% \indextext{\idxcode{main} function!return from}% -Constructed objects\iref{dcl.init} +Constructed complete objects\iref{dcl.init} with static storage duration are destroyed and functions registered with \tcode{std::atexit} are called as part of a call to @@ -7504,29 +7530,69 @@ \end{note} \pnum -Constructed objects with thread storage duration within a given thread +Constructed complete objects with thread storage duration within a given thread are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling \tcode{std::exit}. -The destruction of all constructed objects with thread storage -duration within that thread strongly happens before destroying +The destruction of those constructed objects +is sequenced before releasing the storage for +any object with thread storage duration within that thread\iref{basic.stc.thread}. +The destruction of those constructed objects +strongly happens before destroying any object with static storage duration. \pnum -If the completion of the constructor or dynamic initialization of an object with static -storage duration strongly happens before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. -If the completion of the constructor or dynamic initialization of an object with thread -storage duration is sequenced before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. +The destruction of a complete object with thread storage duration within a given thread +and having constant destruction\iref{expr.const} +is sequenced after the destruction of any other complete object +with thread storage duration within the thread. +The destruction of a complete object with static storage duration +and having constant destruction +is sequenced after the destruction of any other complete object +with static storage duration +and after any call to a function passed to \tcode{std::atexit}. +The sequencing rules in the remainder of this subclause +apply only to complete objects not having constant destruction. + +\pnum +If the deemed construction\iref{dcl.init.general} of a complete object with static +storage duration strongly happens before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. +If the deemed construction of a complete object with thread +storage duration is sequenced before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. If an object is initialized statically, the object is destroyed in the same order as if -the object was dynamically initialized. For an object of array or class -type, all subobjects of that object are destroyed before any block -variable with static storage duration initialized during the construction -of the subobjects is destroyed. +the object was dynamically initialized. If the destruction of an object with static or thread storage duration exits via an exception, the function \tcode{std::terminate} is called\iref{except.terminate}. +\begin{example} +In the following program, +the elements of \tcode{a} are destroyed, +followed by \tocde{dt}, and +finally by the two \tcode{Btemp} objects: +\begin{codeblock} +struct DTemp { ~DTemp(); }; +struct Temp { + ~Temp() { + static DTemp dt; + } +}; +struct BTemp { + ~BTemp(); +}; +struct A { + const BTemp &tb; + ~A(); +}; +A a[] = { (Temp(), BTemp()), BTemp() }; + +int main() {} +\end{codeblock} +If the array \tcode{a} were an object with automatic storage duration, +the \tcode{Btemp} temporaries would be destroyed +as each element of the array is destroyed\iref{class.temporary}. +\end{example} \pnum If a function contains a block variable of static or thread storage duration that has been @@ -7542,12 +7608,13 @@ \pnum \indextext{\idxcode{atexit}}% \indexlibraryglobal{atexit}% -If the completion of the initialization of an object with static storage +If the deemed construction of a complete object with static storage duration strongly happens before a call to \tcode{std::atexit}~(see \libheader{cstdlib}, \ref{support.start.term}), the call to the function passed to -\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a -call to \tcode{std::atexit} strongly happens before the completion of the initialization of -an object with static storage duration, the call to the destructor for the +\tcode{std::atexit} is sequenced before the initiation of the destruction of the object. +If a call to \tcode{std::atexit} strongly happens before the deemed construction of +a complete object with static storage duration, +the completion of the destruction of the object is sequenced before the call to the function passed to \tcode{std::atexit}. If a call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the call to the function passed to the second \tcode{std::atexit} call is sequenced before diff --git a/source/classes.tex b/source/classes.tex index 742e3c6493..adf71d6424 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1704,7 +1704,8 @@ and no virtual base classes\iref{class.mi}, and \item -the constructor selected to copy/move each direct base class subobject is trivial, and +the constructor selected to copy/move each direct base class subobject +is a direct member of that base class and is trivial, and \item for each non-static data member of @@ -1986,7 +1987,7 @@ and no virtual base classes\iref{class.mi}, and \item the assignment operator selected to copy/move each direct -base class subobject is trivial, and +base class subobject is a direct member of that base class and is trivial, and \item for each non-static data member of @@ -3356,7 +3357,8 @@ \indextext{access control!anonymous \tcode{union}}% \indextext{restriction!anonymous \tcode{union}}% Each \grammarterm{member-declaration} in the \grammarterm{member-specification} -of an anonymous union shall either define one or more public non-static data members or +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 shall not be declared within an anonymous union. diff --git a/source/compatibility.tex b/source/compatibility.tex index d0b6bcec85..f89950bdb4 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -3041,6 +3041,33 @@ (for instance, via the C typedef in \libheaderref{stdbool.h}) is ill-formed in \Cpp{}. +\diffref{expr.unary.op} +\change +In certain contexts, +taking the address of a dereferenced null or past-the-end pointer value +is well-defined in C (and yields the original pointer value), +but results in undefined behavior in \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + char *p = nullptr; + char *p2 = &*p; // well-defined in C, undefined behavior in \Cpp{} + char *p3 = &p[0]; // well-defined in C, undefined behavior in \Cpp{} + int a[5]; + int *q = &a[5]; // well-defined in C, undefined behavior in \Cpp{} +} +\end{codeblock} +\end{example} +\rationale +Consistent treatment of lvalues in \Cpp{}. +\effect +Well-formed and well-defined C code exhibits undefined behavior in \Cpp{}. +\difficulty +Syntactic transformation to pointer arithmetic +and possible addition of a check for null pointer values. +\howwide +Occasionally. + \diffref{expr.sizeof,expr.cast} \change In \Cpp{}, types can only be defined in declarations, not in expressions.\\ @@ -3165,6 +3192,24 @@ \rSec2[diff.dcl]{\ref{dcl}: declarations} +\diffref{dcl.pre} +\change +In \Cpp{}, no declaration of a variable can have \cv{} \tcode{void} type. +In C, this is allowed, unless the declaration is a definition. +\begin{example} +\begin{codeblock} +extern void x; // valid C, invalid in \Cpp{} +\end{codeblock} +\end{example} +\rationale +Stricter type checking in \Cpp{}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. + \diffref{dcl.stc} \change In \Cpp{}, the \keyword{static} or \keyword{extern} specifiers can only be applied to names of objects or functions.\\ diff --git a/source/declarations.tex b/source/declarations.tex index 31f91c4c9b..ad156279be 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -2183,7 +2183,11 @@ \opt{\grammarterm{type-constraint}} \keyword{auto} either with a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with -\tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules +\tcode{std::initializer_list}. +If $E$ is a value synthesized for a constant template parameter +of type \tcode{decltype(auto)}\iref{temp.func.order}, +the declaration is ill-formed. +Otherwise, deduce a value for \tcode{U} using the rules of template argument deduction from a function call\iref{temp.deduct.call}, where \tcode{P} is a function template parameter type and @@ -3545,6 +3549,8 @@ of \tcode{N} subobjects of type \tcode{U}, known as the \defnx{elements}{array!element} of the array, and numbered \tcode{0} to \tcode{N-1}. +The element numbered \tcode{0} is termed +the \defnx{first element}{array!first element} of the array. \pnum In addition to declarations in which an incomplete object type is allowed, @@ -3870,6 +3876,10 @@ \end{codeblock} \end{example} +\pnum +A function with a parameter-type-list that has an ellipsis +is termed a \defnadj{vararg}{function}. + \pnum An \defn{explicit-object-parameter-declaration} is a \grammarterm{parameter-declaration} with a \keyword{this} specifier. @@ -4260,10 +4270,10 @@ \indextext{declaration!default argument|(} \pnum -If an \grammarterm{initializer-clause}{} is specified in a -\grammarterm{parameter-declaration}{} this -\grammarterm{initializer-clause}{} -is used as a default argument. +If an \grammarterm{initializer-clause} is specified in a +\grammarterm{parameter-declaration} that is not a +\grammarterm{template-parameter}\iref{temp.param}, +this \grammarterm{initializer-clause} is used as a default argument. \begin{note} Default arguments will be used in calls where trailing arguments are missing\iref{expr.call}. @@ -4294,15 +4304,10 @@ A default argument shall be specified only in the \grammarterm{parameter-declaration-clause} of a function declaration -or \grammarterm{lambda-declarator} -or in a -\grammarterm{template-parameter}\iref{temp.param}. +or \grammarterm{lambda-declarator}. A default argument shall not be specified for -a template parameter pack or a function parameter pack. -If it is specified in a -\grammarterm{parameter-declaration-clause}, -it shall not occur within a +A default argument shall not occur within a \grammarterm{declarator} or \grammarterm{abstract-declarator} @@ -5437,8 +5442,13 @@ \grammarterm{designated-initializer-list}. \pnum -An object whose initialization has completed -is deemed to be constructed, +The \defnadj{deemed}{construction} of an object occurs when +its initialization completes; +for the purposes of~\ref{basic.start.term}, +if the initialization is a full-expression, +deemed construction occurs when +the evaluation of that full-expression completes. +The object is deemed to be constructed, even if the object is of non-class type or no constructor of the object's class is invoked for the initialization. @@ -7710,9 +7720,8 @@ names a complete class type with a member named \tcode{value}, the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression -and -the structured binding size of \tcode{E} is equal to the value of that -expression. +whose value is non-negative; +the structured binding size of \tcode{E} is equal to that value. Let \tcode{i} be an index prvalue of type \tcode{std::size_t} corresponding to $\tcode{v}_i$. If a search for the name \tcode{get} @@ -8963,9 +8972,9 @@ \indextext{name hiding!using-declaration and}% The set of declarations named by a \grammarterm{using-declarator} that inhabits a class \tcode{C} does not include -member functions and member function templates of a base class -that correspond to (and thus would conflict with) -a declaration of a function or function template in \tcode{C}. +member functions and member function templates of a base class that, +when considered as members of \tcode{C}, +correspond to a declaration of a function or function template in \tcode{C}. \begin{example} \begin{codeblock} struct B { @@ -8973,6 +8982,8 @@ virtual void f(char); void g(int); void h(int); + void i(); + void j(); }; struct D : B { @@ -8984,6 +8995,12 @@ using B::h; void h(int); // OK, \tcode{D::h(int)} hides \tcode{B::h(int)} + + using B::i; + void i(this B &); // OK + + using B::j; + void j(this D &); // OK, \tcode{D::j()} hides \tcode{B::j()} }; void k(D* p) @@ -8992,6 +9009,8 @@ p->f('a'); // calls \tcode{B::f(char)} p->g(1); // calls \tcode{B::g(int)} p->g('a'); // calls \tcode{D::g(char)} + p->i(); // calls \tcode{B::i}, because \tcode{B::i} as a member of \tcode{D} is a better match than \tcode{D::i} + p->j(); // calls \tcode{D::j} } struct B1 { diff --git a/source/expressions.tex b/source/expressions.tex index 2bfc4057de..08c4626979 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -714,11 +714,15 @@ \indextext{conversion!array-to-pointer}% \indextext{decay!array|see{conversion, array-to-pointer}}% \indextext{decay!function|see{conversion, function-to-pointer}}% -An lvalue or rvalue of type ``array of \tcode{N} \tcode{T}'' or ``array +An expression $E$ of type ``array of \tcode{N} \tcode{T}'' or ``array of unknown bound of \tcode{T}'' can be converted to a prvalue of type ``pointer to \tcode{T}''. -The temporary materialization conversion\iref{conv.rval} is applied. -The result is a pointer to the first element of the array. +If $E$ is a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. +If the result of $E$ (possibly converted) is an object +whose type is similar to the type of $E$, +the result is a pointer to the first element of the array; +otherwise, the behavior is undefined. \rSec2[conv.func]{Function-to-pointer conversion} @@ -1877,12 +1881,16 @@ A \grammarterm{nested-name-specifier} is \defn{declarative} if it is part of \begin{itemize} \item -a \grammarterm{class-head-name}, +a \grammarterm{class-head-name}\iref{class.pre}, \item -an \grammarterm{enum-head-name}, +an \grammarterm{enum-head-name}\iref{dcl.enum}, \item a \grammarterm{qualified-id} -that is the \grammarterm{id-expression} of a \grammarterm{declarator-id}, or +that is the \grammarterm{id-expression} +of a \grammarterm{declarator-id}\iref{dcl.decl.general}, +\item +an \grammarterm{elaborated-type-specifier} +of an explicit instantiation\iref{temp.explicit}, or \item a declarative \grammarterm{nested-name-specifier}. \end{itemize} @@ -3354,8 +3362,8 @@ \begin{bnf} \nontermdef{type-requirement}\br \keyword{typename} \opt{nested-name-specifier} type-name \terminal{;}\br - \keyword{typename} splice-specifier\br - \keyword{typename} splice-specialization-specifier + \keyword{typename} splice-specifier \terminal{;}\br + \keyword{typename} splice-specialization-specifier \terminal{;} \end{bnf} \pnum @@ -4164,7 +4172,9 @@ For a dot that is followed by an expression that designates a static member or an enumerator, the first expression is a discarded-value expression\iref{expr.context}; -if the expression after the dot designates a non-static data member, +if the expression after the dot designates a +non-static data member\iref{class.mem.general} or +a direct base class relationship\iref{class.derived.general}, the first expression shall be a glvalue. A postfix expression that is followed by an arrow shall be a prvalue having pointer type. @@ -5953,7 +5963,8 @@ \impldef{maximum size of an allocated object} limit\iref{implimits}; or \item -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} and the +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list} and the number of array elements for which initializers are provided (including the terminating \tcode{'\textbackslash 0'} in a \grammarterm{string-literal}\iref{lex.string}) exceeds the number of elements to initialize. @@ -5983,17 +5994,24 @@ \pnum If the allocated type is an array, -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, and +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list}, and the \grammarterm{expression} is potentially-evaluated and not a core constant expression, -the semantic constraints of copy-initializing a hypothetical element of -the array from an empty initializer list -are checked\iref{dcl.init.list}. +the semantic constraints of initializing a hypothetical element of +the array are checked as follows: +\begin{itemize} +\item +If the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, +the hypothetical element is copy-initialized +from an empty initializer list\iref{dcl.init.list}. +\item +Otherwise, the hypothetical element is value-initialized\iref{dcl.init.general}. +\end{itemize} \begin{note} The array can contain more elements than there are -elements in the \grammarterm{braced-init-list}, -requiring initialization of the remainder of the array elements from -an empty initializer list. +elements in the \grammarterm{new-initializer}, +requiring initialization of the remainder of the array elements as appropriate. \end{note} \pnum @@ -8619,6 +8637,13 @@ \item a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}; +\item +pointer arithmetic\iref{expr.add} where +one (possibly converted) operand +points to the first element of an array of unknown bound and +the other (possibly converted) operand +is of integral type with non-zero value; + \item a modification of an object\iref{expr.assign,expr.post.incr,expr.pre.incr} unless it is applied to a non-volatile lvalue of literal type @@ -8677,6 +8702,11 @@ \tcode{std::current_exception} or \tcode{std::rethrow_exception}\iref{propagation} are destroyed within the evaluation of $E$; +\item +a \grammarterm{throw-expression}\iref{expr.throw} with no operand, +unless there is a currently handled exception +whose exception object was constructed within the evaluation of $E$; + \item an \grammarterm{await-expression}\iref{expr.await}; @@ -9147,7 +9177,8 @@ a defaulted special member function that is not declared with the \keyword{consteval} specifier, or \item -a function that results from the instantiation +a function that is not a prospective destructor and +that results from the instantiation of a templated entity defined with the \keyword{constexpr} specifier. \end{itemize} An immediate-escalating expression shall appear only diff --git a/source/lex.tex b/source/lex.tex index 8005b33374..fa52a5c0b1 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -283,7 +283,7 @@ \item \indextext{linking}% Translated translation units are combined, and -all external entity references are resolved. Library +all external entity references are resolved\iref{basic.link}. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information @@ -468,9 +468,8 @@ The \grammarterm{universal-character-name} construct provides a way to name any element in the translation character set using just the basic character set. If a \grammarterm{universal-character-name} outside -the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or -\grammarterm{r-char-sequence} of a \grammarterm{character-literal} or -\grammarterm{string-literal} +the \grammarterm{c-char-sequence} or \grammarterm{s-char-sequence} +of a \grammarterm{character-literal} or \grammarterm{string-literal} (in either case, including within a \grammarterm{user-defined-literal}) corresponds to a control character or to a character in the basic character set, the program is ill-formed. @@ -831,11 +830,11 @@ \pnum In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling. -\begin{footnote} -Thus the ``stringized'' values\iref{cpp.stringize} of -\tcode{[} and \tcode{<:} will be different, maintaining the source -spelling, but the tokens can otherwise be freely interchanged. -\end{footnote} +\begin{note} +The ``stringized'' values\iref{cpp.stringize} of +\tcode{[} and \tcode{<:} are different, +maintaining the source spelling. +\end{note} The set of alternative tokens is defined in \tref{lex.digraph}. @@ -1799,10 +1798,15 @@ \indextext{literal!string}% \begin{bnf} \nontermdef{string-literal}\br - \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br + \opt{encoding-prefix} plain-string-literal\br \opt{encoding-prefix} \terminal{R} raw-string \end{bnf} +\begin{bnf} +\nontermdef{plain-string-literal}\br + \terminal{"} \opt{s-char-sequence} \terminal{"} +\end{bnf} + \begin{bnf} \nontermdef{s-char-sequence}\br s-char \opt{s-char-sequence} diff --git a/source/meta.tex b/source/meta.tex index f0bd37f53d..01e0cf2df6 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -4124,6 +4124,10 @@ \begin{codeblock} if constexpr (is_annotation(@$R$@)) { return @$C$@; +} else if constexpr (is_array_type(type_of(@$R$@))) { + return reflect_constant_array([: @$R$@ :]); +} else if constexpr (is_function_type(type_of(@$R$@))) { + return reflect_function([: @$R$@ :]); } else { return reflect_constant([: @$R$@ :]); } diff --git a/source/modules.tex b/source/modules.tex index cfe20205b1..531ae60135 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -334,8 +334,9 @@ \pnum \begin{note} -Names introduced by exported declarations -have either external linkage or no linkage; see \ref{basic.link}. +Names introduced by exported declarations never have module linkage. +They have external linkage, no linkage, or +(in the case of header units) internal linkage; see \ref{basic.link}. Namespace-scope declarations exported by a module can be found by name lookup in any translation unit importing that module\iref{basic.lookup}. Class and enumeration member names can be found by name lookup in any diff --git a/source/overloading.tex b/source/overloading.tex index 7b882855b9..c967561c1b 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -602,12 +602,16 @@ ``reference to function of ($\tcode{P}_1, \dotsc, \tcode{P}_n$) returning \tcode{R}'', a \defn{surrogate call function} with the unique name \placeholder{call-function} -and having the form +and having a declaration of the form \begin{ncbnf} \terminal{R} \placeholder{call-function} \terminal{(} conversion-type-id \ % -\terminal{F, P$_1$ a$_1$, $\dotsc$, P$_n$ a$_n$)} \terminal{\{} \keyword{return} \terminal{F (a$_1$, $\dotsc$, a$_n$); \}} +\terminal{F, P$_1$ a$_1$, $\dotsc$, P$_n$ a$_n$);}} \end{ncbnf} is also considered as a candidate function. +\begin{note} +If a surrogate call function is selected by overload resolution, +the behavior is as described in~\ref{over.call}. +\end{note} Similarly, surrogate call functions are added to the set of candidate functions for each non-explicit conversion function declared in a base class of @@ -1156,23 +1160,23 @@ the candidate functions are selected as follows: \begin{itemize} \item -Let $R$ be a set of types including +Let $R$ be the set of all \begin{itemize} \item -``lvalue reference to \cvqual{cv2} \tcode{T2}'' +lvalue reference types (when converting to an lvalue) and \item -``\cvqual{cv2} \tcode{T2}'' -and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' -(when converting to an rvalue or an lvalue of function type) +non-reference types and rvalue reference types +(when converting to an rvalue or an lvalue of function type). \end{itemize} -for any \tcode{T2}. The permissible types for non-explicit conversion functions are the members of $R$ +having the form ``\cv{}~\tcode{T2}'' or ``reference to \cvqual{cv2}~\tcode{T2}'' where ``\cvqual{cv1} \tcode{T}'' is reference-compatible\iref{dcl.init.ref} with ``\cvqual{cv2} \tcode{T2}''. For direct-initialization, the permissible types for explicit conversion functions are the members of $R$ +having the form ``\cv{}~\tcode{T2}'' or ``reference to \cvqual{cv2}~\tcode{T2}'' where \tcode{T2} can be converted to type \tcode{T} with a (possibly trivial) qualification conversion\iref{conv.qual}; otherwise there are none. @@ -2397,10 +2401,10 @@ binds directly\iref{dcl.init.ref} to an argument expression: \begin{itemize} \item -If the argument expression has a type that -is a derived class of the parameter type, +If the argument expression has a type \tcode{D} that +is a derived class of \tcode{T}, the implicit conversion sequence is a derived-to-base -conversion\iref{over.best.ics}. +conversion from \tcode{D} to \tcode{T}\iref{over.best.ics}. \item Otherwise, @@ -3079,15 +3083,6 @@ \end{codeblock} \end{example} -\item -binding of an expression of type -\tcode{C} -to a reference to type -\tcode{B} -is better than binding an expression of type -\tcode{C} -to a reference to type -\tcode{A}, \item conversion of \tcode{A::*} @@ -3116,16 +3111,6 @@ to \tcode{A*}, \item -binding of an expression of type -\tcode{B} -to a reference to type -\tcode{A} -is better than binding an expression of type -\tcode{C} -to a -reference to type -\tcode{A}, -\item conversion of \tcode{B::*} to diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 43b2c6a484..214e3d7fca 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -204,8 +204,7 @@ immediately followed on the same logical source line by a \grammarterm{header-name}, \tcode{<}, -\grammarterm{identifier}, -\grammarterm{string-literal}, or +\grammarterm{identifier}, or \tcode{:} preprocessing token, or @@ -354,7 +353,7 @@ \begin{bnf} \nontermdef{header-name-tokens}\br - string-literal\br + plain-string-literal\br \terminal{<} h-pp-tokens \terminal{>} \end{bnf} @@ -757,9 +756,13 @@ in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). -Then, an attempt is made to form a \grammarterm{header-name} +The resulting sequence of preprocessing tokens shall be of the form +\begin{ncsimplebnf} +header-name-tokens +\end{ncsimplebnf} +An attempt is then made to form a \grammarterm{header-name} preprocessing token\iref{lex.header} from the whitespace and the characters -of the spellings of the resulting sequence of preprocessing tokens; +of the spellings of the \grammarterm{header-name-tokens}; the treatment of whitespace is \impldef{treatment of whitespace when processing a \tcode{\#include} directive}. If the attempt succeeds, the directive with the so-formed \grammarterm{header-name} @@ -1305,9 +1308,10 @@ first two forms of \grammarterm{pp-import} is immediately after the \grammarterm{new-line} terminating the \grammarterm{pp-import}. -The last form of \grammarterm{pp-import} is only considered -if the first two forms did not match, and -does not have a point of macro import. +The last form of \grammarterm{pp-import} +does not have a point of macro import, and +is only considered if, after macro replacement, +the first two forms did not match. \pnum If a \grammarterm{pp-import} is produced by source file inclusion @@ -2477,12 +2481,12 @@ \indextext{operator!pragma|see{macro, pragma operator}} \pnum -A unary operator expression of the form: +A unary operator expression of the form \begin{ncbnf} \terminal{_Pragma} \terminal{(} string-literal \terminal{)} \end{ncbnf} is processed as follows: The \grammarterm{string-literal} is \defnx{destringized}{destringization} -by deleting the \tcode{L} prefix, if present, deleting the leading and trailing +by deleting any \grammarterm{encoding-prefix}, deleting the leading and trailing double-quotes, replacing each escape sequence \tcode{\textbackslash"} by a double-quote, and replacing each escape sequence \tcode{\textbackslash\textbackslash} by a single backslash. The resulting sequence of characters is processed through translation phase 3 diff --git a/source/statements.tex b/source/statements.tex index 34018bd618..ad36a30051 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -147,15 +147,12 @@ it is interpreted as the latter. \pnum -In the \grammarterm{decl-specifier-seq} of a \grammarterm{condition} -or of a \grammarterm{for-range-declaration}, -including that of any \grammarterm{structured-binding-declaration} of -the \grammarterm{condition}, +Let $D$ be any \grammarterm{condition} or \grammarterm{for-range-declaration}. +In the \grammarterm{decl-specifier-seq} of $D$, +including that of any \grammarterm{structured-binding-declaration} of $D$, each \grammarterm{decl-specifier} shall be either a \grammarterm{type-specifier} or \keyword{constexpr}. -The \grammarterm{decl-specifier-seq} of a \grammarterm{for-range-declaration} -shall not define a class or enumeration. \rSec1[stmt.label]{Label}% \indextext{statement!labeled} diff --git a/source/templates.tex b/source/templates.tex index 627a70ec8a..e448c62f22 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -496,15 +496,21 @@ \end{itemize} \pnum +Certain constructs refer to template parameter objects, +which are distinct objects with static storage duration and non-volatile const type. +No two such objects have template-argument-equivalent values\iref{temp.type}. An \grammarterm{id-expression} naming a constant template parameter of class type \tcode{T} -denotes a static storage duration object of type \tcode{const T}, -known as a \defn{template parameter object}, -which is template-argument-equivalent\iref{temp.type} to +denotes the template parameter object of type \tcode{const T}, +which is template-argument-equivalent to the corresponding template argument after it has been converted to the type of the template parameter\iref{temp.arg.nontype}. -No two template parameter objects are template-argument-equivalent. +\begin{note} +There can be template parameter objects of array type\iref{meta.define.static}, +but such an object is never denoted by an \grammarterm{id-expression} +that names a constant template parameter. +\end{note} \begin{note} If an \grammarterm{id-expression} names a non-reference constant template parameter, @@ -572,9 +578,8 @@ A \defnadj{default}{template argument} is a template argument\iref{temp.arg} specified after \tcode{=} in a \grammarterm{template-parameter}. -A default template argument may be specified for -any kind of template parameter -that is not a template parameter pack\iref{temp.variadic}. +A default template argument shall not be specified for +a template parameter pack\iref{temp.variadic}. A default template argument may be specified in a template declaration. A default template argument shall not be specified in the \grammarterm{template-parameter-list}{s} @@ -715,10 +720,15 @@ \begin{bnf} \nontermdef{template-argument}\br + template-argument-name\br constant-expression\br - type-id\br - \opt{nested-name-specifier} template-name\br - nested-name-specifier \terminal{template} template-name + type-id +\end{bnf} + +\begin{bnf} +\nontermdef{template-argument-name}\br + \opt{nested-name-specifier} identifier\br + nested-name-specifier \terminal{template} identifier \end{bnf} \pnum @@ -888,6 +898,11 @@ \end{codeblock} \end{example} +\pnum +The component names of a \grammarterm{template-argument-name} are +those of its \grammarterm{nested-name-specifier} (if any) and +its \grammarterm{identifier}. + \pnum A \grammarterm{template-id} or \grammarterm{splice-specialization-specifier} is \defnx{valid}{\idxgram{template-id}!valid} if @@ -1051,6 +1066,29 @@ the $n^\text{th}$ template argument is a pack expansion whose pattern is the name of the template parameter pack. +\pnum +If a \grammarterm{template-argument} $A$ +matches the form \grammarterm{template-argument-name}, +it is interpreted as such; +the identifier is looked up and its meaning is determined as follows: +\begin{itemize} +\item +If lookup finds an injected-class-name\iref{temp.local}, then: +\begin{itemize} +\item When $A$ is for a type template template parameter, +$A$ denotes the corresponding class template. +\item Otherwise, it denotes a \grammarterm{type-name}. +\end{itemize} +\item +Otherwise, if lookup finds a template, +$A$ denotes that template. +\item +Otherwise, if lookup finds a type alias or a type, +$A$ denotes the underlying type and is interpreted as a \grammarterm{type-id}. +\item +Otherwise, $A$ is interpreted as an expression. +\end{itemize} + \pnum In a \grammarterm{template-argument}, @@ -1429,11 +1467,14 @@ template parameter shall be the name of a template. For a \grammarterm{type-tt-parameter}, -the name shall denote a class template or alias template. +the name shall denote a class template, alias template, or +type template template parameter. For a \grammarterm{variable-tt-parameter}, -the name shall denote a variable template. +the name shall denote a variable template or +variable template template parameter. For a \grammarterm{concept-tt-parameter}, -the name shall denote a concept. +the name shall denote a concept or +concept template parameter. Only primary templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template @@ -4372,11 +4413,9 @@ variable template, or concept, respectively, and substitute it for each occurrence of that parameter in the function type of the template. -\begin{note} -The type replacing the placeholder +The type replacing a placeholder in the type of the value synthesized for a constant template parameter -is also a unique synthesized type. -\end{note} +is a unique synthesized type. \pnum %FIXME: What's a "synthesized template"? Do we mean the synthesized @@ -4627,7 +4666,7 @@ that names a specialization of an alias template is a \grammarterm{typedef-name} for a type alias. \begin{note} -An alias template name is never deduced. +The alias template name is not deduced from such a type\iref{temp.deduct.type}. \end{note} \begin{example} \begin{codeblock} @@ -5938,8 +5977,6 @@ \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br fold-expression \end{ncsimplebnf} -unless the \grammarterm{identifier} is a structured binding pack -whose initializer is not dependent. \pnum A \grammarterm{noexcept-expression}\iref{expr.unary.noexcept} @@ -6083,7 +6120,7 @@ A template argument is also dependent if it is a pack expansion. \pnum -A template template parameter is dependent if +A template template argument is dependent if it names a template parameter or its terminal name is dependent. @@ -7998,17 +8035,17 @@ template auto h(T) -> decltype([x = T::invalid]() { }); void h(...); -h(0); // error: invalid expression not part of the immediate context +h(0); // OK, calls \tcode{h(...)} template auto i(T) -> decltype([]() -> typename T::invalid { }); void i(...); -i(0); // error: invalid expression not part of the immediate context +i(0); // OK, calls \tcode{i(...)} template - auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // \#1 -void j(...); // \#2 -j(0); // deduction fails on \#1, calls \#2 + auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); +void j(...); +j(0); // OK, calls \tcode{j(...)} \end{codeblock} \end{example} \end{note} @@ -9390,11 +9427,16 @@ \end{note} \pnum -If \tcode{P} has a form that contains \tcode{}, and -if the type of \tcode{i} differs from the type +If \tcode{P} has a form that contains \tcode{}, +deduction fails unless the type of \tcode{i} is the same as that of the corresponding template parameter +\tcode{p} in the specialization (from \tcode{A}) of the template named by the enclosing \grammarterm{simple-template-id} or -\grammarterm{splice-specialization-specifier}, deduction fails. +\grammarterm{splice-specialization-specifier}; +if the declared type of \tcode{i} contains a placeholder type, +the corresponding template argument for the purposes of +placeholder type deduction\iref{dcl.type.auto.deduct} +is an \grammarterm{id-expression} for \tcode{p}. If \tcode{P} has a form that contains \tcode{[i]}, and if the type of \tcode{i} is not an integral type, deduction fails. \begin{footnote} @@ -9414,15 +9456,54 @@ template void f(A); void k1() { A<1> a; - f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} - f<1>(a); // OK + f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} + f<1>(a); // OK } template class B { }; template void g(B); void k2() { B<1> b; - g(b); // OK, cv-qualifiers are ignored on template parameter types + g(b); // OK, cv-qualifiers are ignored on template parameter types +} + +template struct C; +template void f(C *); +void g(C<0LL> *ap) { + f(ap); // OK, deduces long long value from 0LL +} + +template struct D; +template void f(D *); +void g(D<0LL> *ap) { + f(ap); // OK, deduces x as an int value +} + +template struct E; +template void f(E *); +int v; +void g(E *bp) { + f(bp); // error: type \tcode{int} of \tcode{x} does not match the \tcode{int &} type +} // of the template parameter in the \tcode{E} specialization of \tcode{E} + +template struct F; +template void f(F *); +int i; +void g(F *ap) { + f(ap); // OK, deduces \tcode{x} as a constant template parameter of type \tcode{const int &} +} + +template struct G; +template long *f(G *); // \#1 +template short *f(G *); // \#2 + +const int j = 0; +short *g(G<(j)> *ap) { // OK, \tcode{q} has type \tcode{const int &} + return f(ap); // OK, only \tcode{#2} matches +} + +long *g(G *ap) { // OK, \tcode{q} has type \tcode{int} + return f(ap); // OK, \#1 is more specialized } \end{codeblock} \end{example}