diff --git a/source/basic.tex b/source/basic.tex index 74122bc3b8..bd28e366e0 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -279,8 +279,10 @@ \pnum \indextext{expression!potentially evaluated}% -An expression is \defn{potentially evaluated} unless it is an -unevaluated operand\iref{expr.prop} or a subexpression thereof. +An expression or conversion is \defn{potentially evaluated} unless it is +an unevaluated operand\iref{expr.prop}, +a subexpression thereof, or +a conversion in an initialization or conversion sequence in such a context. The set of \defn{potential results} of an expression \tcode{e} is defined as follows: \begin{itemize} @@ -290,12 +292,17 @@ \item If \tcode{e} is a subscripting operation\iref{expr.sub} with an array operand, the set contains the potential results of that operand. \item If \tcode{e} is a class member access -expression\iref{expr.ref}, the set contains the potential results of -the object expression. +expression\iref{expr.ref} of the form +\tcode{e1 . \opt{template} e2} +naming a non-static data member, +the set contains the potential results of \tcode{e1}. +\item if \tcode{e} is a class member access expression +naming a static data member, +the set contains the \grammarterm{id-expression} designating the data member. \item If \tcode{e} is a pointer-to-member -expression\iref{expr.mptr.oper} whose second operand is a constant -expression, the set contains the potential results of the object -expression. +expression\iref{expr.mptr.oper} of the form +\tcode{e1 .* e2}, +the set contains the potential results of \tcode{e1}. \item If \tcode{e} has the form \tcode{(e1)}, the set contains the potential results of \tcode{e1}. \item If \tcode{e} is a glvalue conditional @@ -322,48 +329,62 @@ \end{note} \pnum -\indextext{function!named by an expression}% -A function is \defn{named by an expression} as follows: +A function is \defnx{named by}{function!named by expression or conversion} +an expression or conversion as follows: \begin{itemize} \item - A function whose name appears in an expression - is named by that expression - if it is the unique lookup result or the selected member - of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}), + A function is named by an expression or conversion + if it is the unique result of a name lookup or the selected member + of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}) + in an overload resolution performed + as part of forming that expression or conversion, unless it is a pure virtual function and either - its name is not explicitly qualified or + the expression is not an \grammarterm{id-expression} naming the function with + an explicitly qualified name or the expression forms a pointer to member\iref{expr.unary.op}. \begin{note} This covers taking the address of functions~(\ref{conv.func}, \ref{expr.unary.op}), calls to named functions\iref{expr.call}, operator overloading\iref{over}, user-defined conversions\iref{class.conv.fct}, - allocation functions for placement \grammarterm{new-expression}{s}\iref{expr.new}, as well as + allocation functions for \grammarterm{new-expression}{s}\iref{expr.new}, as well as non-default initialization\iref{dcl.init}. A constructor selected to copy or move an object of class type - is considered to be named by an expression + is considered to be named by an expression or conversion even if the call is actually elided by the implementation\iref{class.copy.elision}. \end{note} \item - An allocation or deallocation function for a class + A deallocation function for a class is named by a \grammarterm{new-expression} - as specified in~\ref{expr.new} and~\ref{class.free}. + if it is the single matching deallocation function + for the allocation function selected by overload resolution, + as specified in~\ref{expr.new}. \item A deallocation function for a class - is named by a delete expression + is named by a \grammarterm{delete-expression} + if it is the selected usual deallocation function as specified in~\ref{expr.delete} and~\ref{class.free}. \end{itemize} \pnum A variable \tcode{x} whose name appears as a -potentially-evaluated expression \tcode{ex} is \defnx{odr-used}{odr-use} by \tcode{ex} unless -applying the lvalue-to-rvalue conversion\iref{conv.lval} to \tcode{x} yields -a constant expression\iref{expr.const} -that does not invoke a function -other than a trivial special member function\iref{special} -and, if \tcode{x} is an object, \tcode{ex} is an element of -the set of potential results of an expression \tcode{e}, where either the lvalue-to-rvalue -conversion\iref{conv.lval} is applied to \tcode{e}, or \tcode{e} is -a discarded-value expression\iref{expr.prop}. +potentially-evaluated expression \tcode{e} +is \defnx{odr-used}{odr-use} by \tcode{e} unless +\begin{itemize} +\item + \tcode{x} is a reference that is + usable in constant expressions\iref{expr.const}, or +\item + \tcode{x} is a variable of non-reference type that is + usable in constant expressions and has no mutable subobjects, and + \tcode{e} is an element of the set of potential results of an expression + of non-volatile-qualified non-class type + to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or +\item + \tcode{x} is a variable of non-reference type, and + \tcode{e} is an element of the set of potential results + of a discarded-value expression\iref{expr.prop} + to which the lvalue-to-rvalue conversion is not applied. +\end{itemize} \pnum A structured binding is odr-used if it appears as a potentially-evaluated expression. @@ -376,7 +397,8 @@ \pnum A virtual member function is odr-used if it is not pure. -A function is odr-used if it is named by a potentially-evaluated expression. +A function is odr-used if it is named by +a potentially-evaluated expression or conversion. A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the @@ -415,7 +437,10 @@ \begin{itemize} \item the intervening declarative region is a block scope, or \item the intervening declarative region is the function parameter scope of a \grammarterm{lambda-expression} -that has a \grammarterm{simple-capture} naming the entity or has a \grammarterm{capture-default}. +that has a \grammarterm{simple-capture} +naming the entity or has a \grammarterm{capture-default}, and +the block scope of the \grammarterm{lambda-expression} +is also an intervening declarative region. \end{itemize} \end{itemize} @@ -425,11 +450,13 @@ \begin{example} \begin{codeblock} void f(int n) { - [] { n = 1; }; // error, \tcode{n} is not odr-usable due to intervening lambda-expression + [] { n = 1; }; // error: \tcode{n} is not odr-usable due to intervening lambda-expression struct A { - void f() { n = 2; } // error, \tcode{n} is not odr-usable due to intervening function definition scope + void f() { n = 2; } // error: \tcode{n} is not odr-usable due to intervening function definition scope }; - void g(int = n); // error, \tcode{n} is not odr-usable due to intervening function parameter scope + void g(int = n); // error: \tcode{n} is not odr-usable due to intervening function parameter scope + [=](int k = n) {}; // error: \tcode{n} is not odr-usable due to being + // outside the block scope of the \grammarterm{lambda-expression} [&] { [n]{ return n; }; }; // OK } \end{codeblock} @@ -696,9 +723,13 @@ all refer to the same variable, non-static data member, or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is -hidden\iref{basic.scope.hiding}. \begin{note} A namespace name or a -class template name must be unique in its declarative -region~(\ref{namespace.alias}, \ref{temp}). \end{note} +hidden\iref{basic.scope.hiding}. +\begin{note} +A structured binding\iref{dcl.struct.bind}, +namespace name\iref{basic.namespace}, or +class template name\iref{temp} +must be unique in its declarative region. +\end{note} \end{itemize} \begin{note} These restrictions apply to the declarative region into which a name is introduced, which is not necessarily the same as the region in @@ -2373,15 +2404,20 @@ linkage if it is the name of \begin{itemize} \item - a variable, function or function template that is + a variable, variable template, function, or function template that is explicitly declared \tcode{static}; or, \item - a non-inline variable of non-volatile const-qualified type that is + a non-inline non-template variable of non-volatile const-qualified type + that is neither explicitly declared \tcode{extern} nor previously declared to have external linkage; or \item a data member of an anonymous union. \end{itemize} +\begin{note} +An instantiated variable template that has const-qualified type +can have external linkage, even if not declared \tcode{extern}. +\end{note} \pnum An unnamed namespace or a namespace declared directly or indirectly within an @@ -2414,8 +2450,12 @@ \pnum The name of a function declared in block scope and the name of a variable declared by a block scope \tcode{extern} declaration have linkage. If there is a visible declaration -of an entity with linkage having the same name and type, ignoring entities declared -outside the innermost enclosing namespace scope, the block scope declaration declares +of an entity with linkage, ignoring entities declared +outside the innermost enclosing namespace scope, +such that the block scope declaration would be +a (possibly ill-formed) redeclaration +if the two declarations appeared in the same declarative region, +the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage. @@ -2424,9 +2464,11 @@ \begin{example} \begin{codeblock} static void f(); +extern "C" void h(); static int i = 0; // \#1 void g() { extern void f(); // internal linkage + extern void h(); // C language linkage int i; // \#2: \tcode{i} has no linkage { extern void f(); // internal linkage diff --git a/source/classes.tex b/source/classes.tex index 7008d06b61..2d62692deb 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1342,7 +1342,8 @@ of reference type, \item any non-variant non-static data member of const-qualified type (or array -thereof) with no \grammarterm{brace-or-equal-initializer} does not have a user-provided default constructor, +thereof) with no \grammarterm{brace-or-equal-initializer} +is not const-default-constructible\iref{dcl.init}. \item \tcode{X} is a union and all of its variant members are of const-qualified type (or array thereof), diff --git a/source/declarations.tex b/source/declarations.tex index f4cbd195af..cbc953f144 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6153,7 +6153,7 @@ \pnum Otherwise, if the \grammarterm{qualified-id} \tcode{std::tuple_size} -names a complete type, +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 @@ -8071,10 +8071,7 @@ An \grammarterm{alignment-specifier} may also be applied to the declaration of a class (in an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} or -\grammarterm{class-head}\iref{class}, respectively) and to the -declaration of an enumeration (in an -\grammarterm{opaque-enum-declaration} or \grammarterm{enum-head}, -respectively\iref{dcl.enum}). +\grammarterm{class-head}\iref{class}, respectively). An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}. \pnum diff --git a/source/exceptions.tex b/source/exceptions.tex index 438b4fbb0f..6a53134326 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -414,6 +414,12 @@ and whose destructor has not yet begun execution, except that in the case of destruction, the variant members of a union-like class are not destroyed. +\begin{note} +If such an object has a reference member +that extends the lifetime of a temporary object, +this ends the lifetime of the reference member, +so the lifetime of the temporary object is effectively not extended. +\end{note} The subobjects are destroyed in the reverse order of the completion of their construction. Such destruction is sequenced before entering a handler of the \grammarterm{function-try-block} of the constructor or destructor, diff --git a/source/expressions.tex b/source/expressions.tex index 6df82e16cd..0ead83cf27 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -284,32 +284,26 @@ \pnum If a program attempts to access the stored value of an object through a glvalue -of other than one of the following types the behavior is +whose type is not similar\iref{conv.qual} to +one of the following types the behavior is undefined:\footnote{The intent of this list is to specify those circumstances in which an object may or may not be aliased.} \begin{itemize} \item the dynamic type of the object, -\item a cv-qualified version of the dynamic type of the object, - -\item a type similar (as defined in~\ref{conv.qual}) to the dynamic type -of the object, - \item a type that is the signed or unsigned type corresponding to the -dynamic type of the object, - -\item a type that is the signed or unsigned type corresponding to a -cv-qualified version of the dynamic type of the object, - -\item an aggregate or union type that includes one of the aforementioned types among its -elements or non-static data members (including, recursively, an element or non-static data member of a -subaggregate or contained union), - -\item a type that is a (possibly cv-qualified) base class type of the dynamic type of -the object, +dynamic type of the object, or \item a \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} type. \end{itemize} +If a program invokes +a defaulted copy/move constructor or copy/move assignment operator +for a union of type \tcode{U} with a glvalue argument +that does not denote an object of type \cv{}~\tcode{U} within its lifetime, +the behavior is undefined. +\begin{note} +Unlike in C, \Cpp{} has no accesses of class type. +\end{note} \rSec2[expr.type]{Type} @@ -386,8 +380,23 @@ respectively; \item -if \tcode{T1} is ``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U1}'' and \tcode{T2} is -``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U2}'' where \tcode{C1} is +if \tcode{T1} or \tcode{T2} is +``pointer to member of \tcode{C1} of type function'', +the other type is +``pointer to member of \tcode{C2} of type \tcode{noexcept} function'', and +\tcode{C1} is reference-related to \tcode{C1} or +\tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, +where the function types are otherwise the same, +``pointer to member of \tcode{C2} of type function'' or +``pointer to member of \tcode{C1} of type function'', respectively; + +\item +if \tcode{T1} is +``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U}'' and +\tcode{T2} is +``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U}'', +for some non-function type \tcode{U}, +where \tcode{C1} is reference-related to \tcode{C2} or \tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, the cv-combined type of \tcode{T2} and \tcode{T1} or the cv-combined type of \tcode{T1} and \tcode{T2}, respectively; @@ -713,7 +722,7 @@ $\cv{}_i$ and $P_i$ such that \tcode{T} is \begin{indented} -``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n > 0$, +``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n \geq 0$, \end{indented} where each $\cv{}_i$ is a set of cv-qualifiers\iref{basic.type.qualifier}, and @@ -1475,9 +1484,13 @@ \grammarterm{unqualified-id} is a \grammarterm{conversion-function-id}, its \grammarterm{conversion-type-id} -shall denote the same type in both the context in which the entire -\grammarterm{qualified-id} occurs and in the context of the class denoted -by the \grammarterm{nested-name-specifier}. +is first looked up in the class denoted by +the \grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} and +the name, if found, is used. +Otherwise, it is looked up in the context in which +the entire \grammarterm{qualified-id} occurs. +In each of these lookups, only names that denote types or +templates whose specializations are types are considered. \rSec3[expr.prim.id.dtor]{Destruction} @@ -1766,11 +1779,14 @@ has a non-throwing exception specification. The value returned by this conversion function is the address of a function \tcode{F} that, when invoked, -has the same effect as invoking the closure type's function call operator. +has the same effect as invoking the closure type's function call operator +on a default-constructed instance of the closure type. \tcode{F} is a constexpr function if the function call operator is a constexpr function and is an immediate function if the function call operator is an immediate function. + +\pnum For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a conversion function template to pointer to function. The conversion function template has the same invented @@ -1835,9 +1851,11 @@ The value returned by any given specialization of this conversion function template is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator -template specialization. +template specialization on a default-constructed instance of the closure type. \tcode{F} is a constexpr function -if the corresponding specialization is a constexpr function. +if the corresponding specialization is a constexpr function and +\tcode{F} is an immediate function +if the function call operator template specialization is an immediate function. \begin{note} This will result in the implicit instantiation of the generic lambda's body. The instantiated generic lambda's return type and parameter types shall match @@ -3367,15 +3385,13 @@ the result is \tcode{v} (converted if necessary). -\pnum -If the value of \tcode{v} is a null pointer value in the pointer case, -the result is the null pointer value of type \tcode{T}. - \pnum If \tcode{T} is ``pointer to \cvqual{cv1} \tcode{B}'' and \tcode{v} has type ``pointer to \cvqual{cv2} \tcode{D}'' such that \tcode{B} is a base class of \tcode{D}, the result is a pointer to the unique \tcode{B} -subobject of the \tcode{D} object pointed to by \tcode{v}. Similarly, if +subobject of the \tcode{D} object pointed to by \tcode{v}, or +a null pointer value if \tcode{v} is a null pointer value. +Similarly, if \tcode{T} is ``reference to \cvqual{cv1} \tcode{B}'' and \tcode{v} has type \cvqual{cv2} \tcode{D} such that \tcode{B} is a base class of \tcode{D}, the result is the unique \tcode{B} subobject of the \tcode{D} @@ -3401,6 +3417,9 @@ Otherwise, \tcode{v} shall be a pointer to or a glvalue of a polymorphic type\iref{class.virtual}. +\pnum +If \tcode{v} is a null pointer value, the result is a null pointer value. + \pnum If \tcode{T} is ``pointer to \cv{} \tcode{void}'', then the result is a pointer to the most derived object pointed to by \tcode{v}. @@ -5901,9 +5920,11 @@ \end{itemize} \pnum -If at least one of the operands is a pointer to member, pointer-to-member -conversions\iref{conv.mem} and qualification -conversions\iref{conv.qual} are performed on both operands to bring them to +If at least one of the operands is a pointer to member, +pointer-to-member conversions\iref{conv.mem}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed on both operands to bring them to their composite pointer type\iref{expr.type}. Comparing pointers to members is defined as follows: @@ -6275,8 +6296,10 @@ pointer type. \item One or both of the second and third operands have pointer-to-member type; -pointer to member conversions\iref{conv.mem} and qualification -conversions\iref{conv.qual} are performed to bring them to their composite +pointer to member conversions\iref{conv.mem}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. \item @@ -6696,12 +6719,8 @@ a \grammarterm{delete-expression}\iref{expr.delete}; \item -a three-way comparison\iref{expr.spaceship} -comparing pointers that do not point to the same -complete object or to any subobject thereof; - -\item -a relational\iref{expr.rel} or equality\iref{expr.eq} +a three-way comparison\iref{expr.spaceship}, +relational\iref{expr.rel}, or equality\iref{expr.eq} operator where the result is unspecified; \item diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 73eb33690a..5ecb503d8b 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1477,7 +1477,9 @@ Two kinds of implementations are defined: \defnx{hosted}{implementation!hosted} and -\defnx{freestanding}{implementation!freestanding}\iref{intro.compliance}. +\defnx{freestanding}{implementation!freestanding}\iref{intro.compliance}; +the kind of the implementation is +\impldef{whether the implementation is hosted or freestanding}. For a hosted implementation, this document describes the set of available headers. diff --git a/source/templates.tex b/source/templates.tex index c9008923a7..80584fce67 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2967,8 +2967,9 @@ \pnum When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include -default arguments, nor shall the inline specifier be used in such a -declaration. +default arguments, nor shall +the \tcode{inline}, \tcode{constexpr}, or \tcode{consteval} specifiers +be used in such a declaration. \pnum A non-template friend declaration shall not have a \grammarterm{requires-clause}. @@ -4932,8 +4933,8 @@ of the \grammarterm{id-expression} does not find a member of a class that is the current instantiation or a non-dependent base class thereof; or -\item the type of the object expression is dependent and is not the current -instantiation. +\item the type of the object expression is not the current instantiation +and the object expression is type-dependent. \end{itemize} \end{itemize} @@ -6809,7 +6810,8 @@ \pnum \indextext{specification!template argument}% Template arguments can be specified when referring to a function -template specialization by qualifying the function template +template specialization that is not a specialization of a constructor template +by qualifying the function template name with the list of \grammarterm{template-argument}{s} in the same way as @@ -6834,6 +6836,11 @@ \end{codeblock} \end{example} +\pnum +Template arguments shall not be specified +when referring to a specialization of +a constructor template~(\ref{class.ctor}, \ref{class.qual}). + \pnum A template argument list may be specified when referring to a specialization of a function template @@ -7781,44 +7788,6 @@ \tcode{A}, the type deduction fails. -\pnum -When the deduction process requires a qualification conversion for a -pointer or pointer-to-member type as described above, the following -process is used to determine the deduced template argument values: - -If -\tcode{A} -is a type -\begin{indented} -$\cv{}_{1,0}$ ``pointer to $\ldots$'' $\cv{}_{1,n-1}$ ``pointer to'' -$\cv{}_{1,n}$ \tcode{T1} -\end{indented} -and -\tcode{P} -is a type -\begin{indented} -$\cv{}_{2,0}$ ``pointer to $\ldots$'' $\cv{}_{2,n-1}$ ``pointer to'' -$\cv{}_{2,n}$ \tcode{T2}, -\end{indented} -then the cv-unqualified -\tcode{T1} -and -\tcode{T2} -are used as the types of -\tcode{A} -and -\tcode{P} -respectively for type deduction. -\begin{example} -\begin{codeblock} -struct A { - template operator T***(); -}; -A a; -const int * const * const * p1 = a; // \tcode{T} deduced as \tcode{int}, not \tcode{const int} -\end{codeblock} -\end{example} - \rSec3[temp.deduct.partial]{Deducing template arguments during partial ordering} \pnum