diff --git a/source/basic.tex b/source/basic.tex index 9524265f81..ef90efa309 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1,20 +1,15 @@ %!TEX root = std.tex \rSec0[basic]{Basics} -\gramSec[gram.basic]{Basics} - \rSec1[basic.pre]{Preamble} \pnum \begin{note} This Clause presents the basic concepts of the \Cpp{} language. -It explains the difference between an object and a -name and how they relate to the value categories for expressions. It introduces the concepts of a declaration and a definition and presents \Cpp{}'s -notion of type, scope, linkage, and -storage duration. The mechanisms for starting and -terminating a program are discussed. Finally, this Clause presents the +notion of type, scope, and +storage duration. Finally, this Clause presents the fundamental types of the language and lists the ways of constructing compound types from these. \end{note} @@ -26,7173 +21,6760 @@ Clauses. \end{note} -\pnum -\indextext{type}% -\indextext{object}% -\indextext{storage class}% -\indextext{scope}% -\indextext{linkage}% -An \defn{entity} is a value, object, reference, -structured binding, -function, enumerator, type, -class member, bit-field, template, template specialization, namespace, or -pack. +\rSec1[basic.exec]{Program execution} + +\rSec2[intro.execution]{Sequential execution} +\indextext{program execution|(} \pnum -A \defn{name} is an \grammarterm{identifier}\iref{lex.name}, -\grammarterm{operator-function-id}\iref{over.oper}, -\grammarterm{literal-operator-id}\iref{over.literal}, or -\grammarterm{conversion-function-id}\iref{class.conv.fct}. +An instance of each object with automatic storage +duration\iref{basic.stc.auto} is associated with each entry into its +block\iref{defns.block.stmt}. Such an object exists and retains its last-stored value during +the execution of the block and while the block is suspended (by a call +of a function, suspension of a coroutine\iref{expr.await}, or receipt of a signal). \pnum -Every name is introduced by a \defn{declaration}, which is a +A \defn{constituent expression} is defined as follows: \begin{itemize} \item -\grammarterm{name-declaration}, -\grammarterm{block-declaration}, or -\grammarterm{member-declaration}\iref{dcl.pre,class.mem}, -\item -\grammarterm{init-declarator}\iref{dcl.decl}, -\item -\grammarterm{identifier} -in a structured binding declaration\iref{dcl.struct.bind}, -\item -\grammarterm{init-capture}\iref{expr.prim.lambda.capture}, -\item -\grammarterm{condition} with a \grammarterm{declarator}\iref{stmt.pre}, -\item -\grammarterm{member-declarator}\iref{class.mem}, +The constituent expression of an expression is that expression. \item -\grammarterm{using-declarator}\iref{namespace.udecl}, +The constituent expression of a conversion is +the corresponding implicit function call, if any, or +the converted expression otherwise. \item -\grammarterm{parameter-declaration}\iref{dcl.fct}, +The constituent expressions of a \grammarterm{braced-init-list} or +of a (possibly parenthesized) \grammarterm{expression-list} +are the constituent expressions of the elements of the respective list. \item -\grammarterm{type-parameter}\iref{temp.param}, +The constituent expressions of a \grammarterm{brace-or-equal-initializer} +of the form \tcode{=}~\grammarterm{initializer-clause} +are the constituent expressions of the \grammarterm{initializer-clause}. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { int x; }; +struct B { int y; struct A a; }; +B b = { 5, { 1+1 } }; +\end{codeblock} +The constituent expressions of the \grammarterm{initializer} +used for the initialization of \tcode{b} are \tcode{5} and \tcode{1+1}. +\end{example} + +\pnum +The \defnx{immediate subexpressions}{immediate subexpression} of an expression $E$ are +\begin{itemize} \item -\grammarterm{elaborated-type-specifier} -that introduces a name\iref{dcl.type.elab}, +the constituent expressions of $E$'s operands\iref{expr.prop}, \item -\grammarterm{class-specifier}\iref{class.pre}, +any function call that $E$ implicitly invokes, \item -\grammarterm{enum-specifier} or -\grammarterm{enumerator-definition}\iref{dcl.enum}, +if $E$ is a \grammarterm{lambda-expression}\iref{expr.prim.lambda}, +the initialization of the entities captured by copy and +the constituent expressions of the \grammarterm{initializer} of the \grammarterm{init-capture}{s}, \item -\grammarterm{exception-declaration}\iref{except.pre}, or +if $E$ is a function call\iref{expr.call} or implicitly invokes a function, +the constituent expressions of each default argument\iref{dcl.fct.default} +used in the call, or \item -implicit declaration of an injected-class-name\iref{class.pre}. -\end{itemize} -\begin{note} -The interpretation of a \grammarterm{for-range-declaration} produces -one or more of the above\iref{stmt.ranged}. -\end{note} -An entity $E$ is denoted by the name (if any) -that is introduced by a declaration of $E$ or -by a \grammarterm{typedef-name} introduced by a declaration specifying $E$. - -\pnum -A \defn{variable} is introduced by the -declaration of -a reference other than a non-static data member or of -an object. The variable's name, if any, denotes the reference or object. - -\pnum -A \defnadj{local}{entity} is a variable with -automatic storage duration\iref{basic.stc.auto}, -a structured binding\iref{dcl.struct.bind} -whose corresponding variable is such an entity, -or the \tcode{*\keyword{this}} object\iref{expr.prim.this}. - -\pnum -Some names denote types or templates. In general, -whenever a name is encountered it is necessary to determine whether that name denotes -one of these entities before continuing to parse the program that contains it. The -process that determines this is called -\defnx{name lookup}{lookup!name}\iref{basic.lookup}. - -\pnum -Two names are \defnx{the same}{name!same} if -\begin{itemize} -\item they are \grammarterm{identifier}{s} composed of the same character sequence, or -\item they are \grammarterm{operator-function-id}{s} formed with -the same operator, or -\item they are \grammarterm{conversion-function-id}{s} formed -with equivalent\iref{temp.over.link} types, or -\item they are \grammarterm{literal-operator-id}{s}\iref{over.literal} formed with -the same literal suffix identifier. +if $E$ creates an aggregate object\iref{dcl.init.aggr}, +the constituent expressions of each default member initializer\iref{class.mem} +used in the initialization. \end{itemize} \pnum -\indextext{translation unit!name and}% -\indextext{linkage}% -A name used in more than one translation unit can potentially -refer to the same entity in these translation units depending on the -linkage\iref{basic.link} of the name specified in each -translation unit. - -\rSec1[basic.def]{Declarations and definitions} - -\pnum -\indextext{declaration!definition versus}% -\indextext{declaration}% -\indextext{declaration!name}% -A declaration\iref{dcl.dcl} may (re)introduce -one or more names and/or entities into a translation -unit. -If so, the -declaration specifies the interpretation and semantic properties of these names. -A declaration of an entity or \grammarterm{typedef-name} $X$ is -a redeclaration of $X$ -if another declaration of $X$ is reachable from it\iref{module.reach}. -A declaration may also have effects including: +A \defn{subexpression} of an expression $E$ is +an immediate subexpression of $E$ or +a subexpression of an immediate subexpression of $E$. +\begin{note} +Expressions appearing in the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +are not subexpressions of the \grammarterm{lambda-expression}. +\end{note} +The \defnadjx{potentially-evaluated}{subexpressions}{subexpression} of +an expression, conversion, or \grammarterm{initializer} $E$ are \begin{itemize} -\item a static assertion\iref{dcl.pre}, -\item controlling template instantiation\iref{temp.explicit}, -\item guiding template argument deduction for constructors\iref{temp.deduct.guide}, -\item use of attributes\iref{dcl.attr}, and -\item nothing (in the case of an \grammarterm{empty-declaration}). +\item +the constituent expressions of $E$ and +\item +the subexpressions thereof that +are not subexpressions of a nested unevaluated operand\iref{term.unevaluated.operand}. \end{itemize} \pnum -\indextext{declaration!function}% -\indextext{definition}% -Each entity declared by a \grammarterm{declaration} is -also \defnx{defined}{define} by that declaration unless: +A \defn{full-expression} is \begin{itemize} \item -it declares a function -without specifying the function's body\iref{dcl.fct.def}, -\item -it contains -the -\indextext{declaration!\idxcode{extern}}% -\keyword{extern} specifier\iref{dcl.stc} or a -\grammarterm{linkage-specification} -\begin{footnote} -Appearing inside the brace-enclosed -\grammarterm{declaration-seq} in a \grammarterm{linkage-specification} does -not affect whether a declaration is a definition. -\end{footnote} -\iref{dcl.link} -and neither an \grammarterm{initializer} nor a -\grammarterm{function-body}, -\item -\indextext{declaration!static member@\tcode{static} member}% -it declares a non-inline static data member in a class -definition\iref{class.mem,class.static}, -\item -it declares a static data member outside a class definition -and the variable was defined within the class with the \keyword{constexpr} -specifier\iref{class.static.data} (this usage is deprecated; see \ref{depr.static.constexpr}), -\item -\indextext{declaration!class name}% -it is an \grammarterm{elaborated-type-specifier}\iref{class.name}, -\item -it is an -\indextext{declaration!opaque enum}% -\grammarterm{opaque-enum-declaration}\iref{dcl.enum}, +an unevaluated operand\iref{expr.context}, \item -it is a -\indextext{parameter!template}\indextext{template parameter}% -\grammarterm{template-parameter}\iref{temp.param}, +a \grammarterm{constant-expression}\iref{expr.const}, \item -it is a -\indextext{declaration!parameter}\indextext{parameter declaration}% -\grammarterm{parameter-declaration}\iref{dcl.fct} in a function -\indextext{declarator}% -declarator that is not the \grammarterm{declarator} of a -\grammarterm{function-definition}, +an immediate invocation\iref{expr.const}, \item -it is a -\indextext{declaration!\idxcode{typedef}}% -\keyword{typedef} declaration\iref{dcl.typedef}, -\item it is -an \grammarterm{alias-declaration}\iref{dcl.typedef}, -\item it is -a -\grammarterm{using-declaration}\iref{namespace.udecl}, -\item it is -a \grammarterm{deduction-guide}\iref{temp.deduct.guide}, -\item it is -a \grammarterm{static_assert-declaration}\iref{dcl.pre}, +an \grammarterm{init-declarator}\iref{dcl.decl} +(including such introduced by a structured binding\iref{dcl.struct.bind}) or +a \grammarterm{mem-initializer}\iref{class.base.init}, +including the constituent expressions of the initializer, \item -it is an -\grammarterm{attribute-declaration}\iref{dcl.pre}, +an invocation of a destructor generated at the end of the lifetime +of an object other than a temporary object\iref{class.temporary} +whose lifetime has not been extended, or \item -it is an -\grammarterm{empty-declaration}\iref{dcl.pre}, -\item it is -a \grammarterm{using-directive}\iref{namespace.udir}, -\item it is -a \grammarterm{using-enum-declaration}\iref{enum.udecl}, -\item it is -a \grammarterm{template-declaration}\iref{temp.pre} -whose \grammarterm{template-head} is not followed by -either a \grammarterm{concept-definition} or a \grammarterm{declaration} -that defines a function, a class, a variable, or a static data member, -\item it is -an explicit instantiation declaration\iref{temp.explicit}, or -\item it is -an explicit specialization\iref{temp.expl.spec} whose -\grammarterm{declaration} is not a definition. +an expression that is not a subexpression of another expression and +that is not otherwise part of a full-expression. \end{itemize} -A declaration is said to be a \defn{definition} of each entity that it defines. +If a language construct is defined to produce an implicit call of a function, +a use of the language construct is considered to be an expression +for the purposes of this definition. +Conversions applied to the result of an expression in order to satisfy the requirements +of the language construct in which the expression appears +are also considered to be part of the full-expression. +For an initializer, performing the initialization of the entity +(including evaluating default member initializers of an aggregate) +is also considered part of the full-expression. \begin{example} -All but one of the following are definitions: \begin{codeblock} -int a; // defines \tcode{a} -extern const int c = 1; // defines \tcode{c} -int f(int x) { return x+a; } // defines \tcode{f} and defines \tcode{x} -struct S { int a; int b; }; // defines \tcode{S}, \tcode{S::a}, and \tcode{S::b} -struct X { // defines \tcode{X} - int x; // defines non-static data member \tcode{x} - static int y; // declares static data member \tcode{y} - X(): x(0) { } // defines a constructor of \tcode{X} +struct S { + S(int i): I(i) { } // full-expression is initialization of \tcode{I} + int& v() { return I; } + ~S() noexcept(false) { } +private: + int I; }; -int X::y = 1; // defines \tcode{X::y} -enum { up, down }; // defines \tcode{up} and \tcode{down} -namespace N { int d; } // defines \tcode{N} and \tcode{N::d} -namespace N1 = N; // defines \tcode{N1} -X anX; // defines \tcode{anX} -\end{codeblock} -whereas these are just declarations: -\begin{codeblock} -extern int a; // declares \tcode{a} -extern const int c; // declares \tcode{c} -int f(int); // declares \tcode{f} -struct S; // declares \tcode{S} -typedef int Int; // declares \tcode{Int} -extern X anotherX; // declares \tcode{anotherX} -using N::d; // declares \tcode{d} +S s1(1); // full-expression comprises call of \tcode{S::S(int)} +void f() { + S s2 = 2; // full-expression comprises call of \tcode{S::S(int)} + if (S(3).v()) // full-expression includes lvalue-to-rvalue and \tcode{int} to \tcode{bool} conversions, + // performed before temporary is deleted at end of full-expression + { } + bool b = noexcept(S(4)); // exception specification of destructor of \tcode{S} considered for \keyword{noexcept} + + // full-expression is destruction of \tcode{s2} at end of block +} +struct B { + B(S = S(0)); +}; +B b[2] = { B(), B() }; // full-expression is the entire initialization + // including the destruction of temporaries \end{codeblock} \end{example} \pnum \begin{note} -\indextext{implementation-generated}% -In some circumstances, \Cpp{} implementations implicitly define the -default constructor\iref{class.default.ctor}, -copy constructor, move constructor\iref{class.copy.ctor}, -copy assignment operator, move assignment operator\iref{class.copy.assign}, -or destructor\iref{class.dtor} member functions. +The evaluation of a full-expression can include the +evaluation of subexpressions that are not lexically part of the +full-expression. For example, subexpressions involved in evaluating +default arguments\iref{dcl.fct.default} are considered to +be created in the expression that calls the function, not the expression +that defines the default argument. \end{note} -\begin{example} -Given -\begin{codeblock} -#include -struct C { - std::string s; // \tcode{std::string} is the standard library class\iref{string.classes} -}; +\pnum +\indextext{value computation|(}% +Reading an object designated by a \keyword{volatile} +glvalue\iref{basic.lval}, modifying an object, calling a library I/O +function, or calling a function that does any of those operations are +all +\defn{side effects}, which are changes in the state of the execution +environment. \defnx{Evaluation}{evaluation} of an expression (or a +subexpression) in general includes both value computations (including +determining the identity of an object for glvalue evaluation and fetching +a value previously assigned to an object for prvalue evaluation) and +initiation of side effects. When a call to a library I/O function +returns or an access through a volatile glvalue is evaluated, the side +effect is considered complete, even though some external actions implied +by the call (such as the I/O itself) or by the \keyword{volatile} access +may not have completed yet. -int main() { - C a; - C b = a; - b = a; -} -\end{codeblock} -the implementation will implicitly define functions to make the -definition of \tcode{C} equivalent to +\pnum +\defnx{Sequenced before}{sequenced before} is an asymmetric, transitive, pair-wise relation between +evaluations executed by a single thread\iref{intro.multithread}, which induces +a partial order among those evaluations. Given any two evaluations \placeholder{A} and +\placeholder{B}, if \placeholder{A} is sequenced before \placeholder{B} +(or, equivalently, \placeholder{B} is \defn{sequenced after} \placeholder{A}), +then the execution of +\placeholder{A} shall precede the execution of \placeholder{B}. If \placeholder{A} is not sequenced +before \placeholder{B} and \placeholder{B} is not sequenced before \placeholder{A}, then \placeholder{A} and +\placeholder{B} are \defn{unsequenced}. +\begin{note} +The execution of unsequenced +evaluations can overlap. +\end{note} +Evaluations \placeholder{A} and \placeholder{B} are +\defn{indeterminately sequenced} when either \placeholder{A} is sequenced before +\placeholder{B} or \placeholder{B} is sequenced before \placeholder{A}, but it is unspecified which. +\begin{note} +Indeterminately sequenced evaluations cannot overlap, but either +can be executed first. +\end{note} +An expression \placeholder{X} +is said to be sequenced before +an expression \placeholder{Y} if +every value computation and every side effect +associated with the expression \placeholder{X} +is sequenced before +every value computation and every side effect +associated with the expression \placeholder{Y}. + +\pnum +Every +\indextext{value computation}% +value computation and +\indextext{side effects}% +side effect associated with a full-expression is +sequenced before every value computation and side effect associated with the +next full-expression to be evaluated. +\begin{footnote} +As specified +in~\ref{class.temporary}, after a full-expression is evaluated, a sequence of +zero or more invocations of destructor functions for temporary objects takes +place, usually in reverse order of the construction of each temporary object. +\end{footnote} + +\pnum +\indextext{evaluation!unspecified order of}% +Except where noted, evaluations of operands of individual operators and +of subexpressions of individual expressions are unsequenced. +\begin{note} +In an expression that is evaluated more than once during the execution +of a program, unsequenced and indeterminately sequenced evaluations of +its subexpressions need not be performed consistently in different +evaluations. +\end{note} +The value computations of the operands of an +operator are sequenced before the value computation of the result of the +operator. If a +\indextext{side effects}% +side effect on a memory location\iref{intro.memory} is unsequenced +relative to either another side effect on the same memory location or +a value computation using the value of any object in the same memory location, +and they are not potentially concurrent\iref{intro.multithread}, +the behavior is undefined. +\begin{note} +The next subclause imposes similar, but more complex restrictions on +potentially concurrent computations. +\end{note} + +\begin{example} \begin{codeblock} -struct C { - std::string s; - C() : s() { } - C(const C& x): s(x.s) { } - C(C&& x): s(static_cast(x.s)) { } - @\rlap{\textnormal{\textit{//}}}@ : s(std::move(x.s)) { } - C& operator=(const C& x) { s = x.s; return *this; } - C& operator=(C&& x) { s = static_cast(x.s); return *this; } - @\rlap{\textnormal{\textit{//}}}@ { s = std::move(x.s); return *this; } - ~C() { } -}; +void g(int i) { + i = 7, i++, i++; // \tcode{i} becomes \tcode{9} + + i = i++ + 1; // the value of \tcode{i} is incremented + i = i++ + i; // undefined behavior + i = i + 1; // the value of \tcode{i} is incremented +} \end{codeblock} \end{example} \pnum +When invoking a function (whether or not the function is inline), +every argument expression and +the postfix expression designating the called function +are sequenced before every expression or statement +in the body of the called function. +For each function invocation or +evaluation of an \grammarterm{await-expression} \placeholder{F}, +each evaluation that does not occur within \placeholder{F} but +is evaluated on the same thread and as part of the same signal handler (if any) +is either sequenced before all evaluations that occur within \placeholder{F} +or sequenced after all evaluations that occur within \placeholder{F}; +\begin{footnote} +In other words, +function executions do not interleave with each other. +\end{footnote} +if \placeholder{F} invokes or resumes a coroutine\iref{expr.await}, +only evaluations +subsequent to the previous suspension (if any) and +prior to the next suspension (if any) +are considered to occur within \placeholder{F}. + +Several contexts in \Cpp{} cause evaluation of a function call, even +though no corresponding function call syntax appears in the translation +unit. +\begin{example} +Evaluation of a \grammarterm{new-expression} invokes one or more allocation +and constructor functions; see~\ref{expr.new}. For another example, +invocation of a conversion function\iref{class.conv.fct} can arise in +contexts in which no function call syntax appears. +\end{example} +The sequencing constraints on the execution of the called function (as +described above) are features of the function calls as evaluated, +regardless of the syntax of the expression that calls the function.% +\indextext{value computation|)}% + +\indextext{behavior!on receipt of signal}% +\indextext{signal}% +\pnum +If a signal handler is executed as a result of a call to the \tcode{std::raise} +function, then the execution of the handler is sequenced after the invocation +of the \tcode{std::raise} function and before its return. \begin{note} -A class name can also be implicitly declared by an -\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}. +When a signal is received for another reason, the execution of the +signal handler is usually unsequenced with respect to the rest of the program. \end{note} +\rSec2[intro.multithread]{Multi-threaded executions and data races} + +\rSec3[intro.multithread.general]{General} + \pnum -\indextext{type!incomplete}% -In the definition of an object, -the type of that object shall not be -an incomplete type\iref{term.incomplete.type}, -an abstract class type\iref{class.abstract}, or -a (possibly multidimensional) array thereof. +\indextext{threads!multiple|(}% +\indextext{atomic!operation|(}% +A \defn{thread of execution} (also known as a \defn{thread}) is a single flow of +control within a program, including the initial invocation of a specific +top-level function, and recursively including every function invocation +subsequently executed by the thread. +\begin{note} +When one thread creates another, +the initial call to the top-level function of the new thread is executed by the +new thread, not by the creating thread. +\end{note} +Every thread in a program can +potentially access every object and function in a program. +\begin{footnote} +An object +with automatic or thread storage duration\iref{basic.stc} is associated with +one specific thread, and can be accessed by a different thread only indirectly +through a pointer or reference\iref{basic.compound}. +\end{footnote} +Under a hosted +implementation, a \Cpp{} program can have more than one thread running +concurrently. The execution of each thread proceeds as defined by the remainder +of this document. The execution of the entire program consists of an execution +of all of its threads. +\begin{note} +Usually the execution can be viewed as an +interleaving of all its threads. However, some kinds of atomic operations, for +example, allow executions inconsistent with a simple interleaving, as described +below. +\end{note} +\indextext{implementation!freestanding}% +Under a freestanding implementation, it is \impldef{number of +threads in a program under a freestanding implementation} whether a program can +have more than one thread of execution. -\rSec1[basic.def.odr]{One-definition rule}% -\indextext{object!definition}% -\indextext{function!definition}% -\indextext{class!definition}% -\indextext{enumerator!definition}% -\indextext{one-definition rule|(}% +\pnum +For a signal handler that is not executed as a result of a call to the +\tcode{std::raise} function, it is unspecified which thread of execution +contains the signal handler invocation. + +\rSec3[intro.races]{Data races} \pnum -Each of the following is termed a \defnadj{definable}{item}: -\begin{itemize} -\item a class type\iref{class}, -\item an enumeration type\iref{dcl.enum}, -\item a function\iref{dcl.fct}, -\item a variable\iref{basic.pre}, -\item a templated entity\iref{temp.pre}, -\item a default argument for a parameter -(for a function in a given scope)\iref{dcl.fct.default}, or -\item a default template argument\iref{temp.param}. -\end{itemize} +The value of an object visible to a thread $T$ at a particular point is the +initial value of the object, a value assigned to the object by $T$, or a +value assigned to the object by another thread, according to the rules below. +\begin{note} +In some cases, there might instead be undefined behavior. Much of this +subclause is motivated by the desire to support atomic operations with explicit +and detailed visibility constraints. However, it also implicitly supports a +simpler view for more restricted programs. +\end{note} \pnum -No translation unit shall contain more than one definition of any -definable item. +Two expression evaluations \defn{conflict} if one of them modifies a memory +location\iref{intro.memory} and the other one reads or modifies the same +memory location. \pnum -\indextext{expression!potentially evaluated}% -An expression or conversion is \defn{potentially evaluated} unless it is -an unevaluated operand\iref{expr.context}, -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 $E$ is -defined as follows: -\begin{itemize} -\item If $E$ is an -\grammarterm{id-expression}\iref{expr.prim.id}, the set -contains only $E$. -\item If $E$ is a subscripting operation\iref{expr.sub} with -an array operand, the set contains the potential results of that operand. -\item If $E$ is a class member access -expression\iref{expr.ref} of the form -$E_1$ \tcode{.} \opt{\keyword{template}} $E_2$ -naming a non-static data member, -the set contains the potential results of $E_1$. -\item If $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 $E$ is a pointer-to-member -expression\iref{expr.mptr.oper} of the form -$E_1$ \tcode{.*} $E_2$, -the set contains the potential results of $E_1$. -\item If $E$ has the form \tcode{($E_1$)}, the set contains the -potential results of $E_1$. -\item If $E$ is a glvalue conditional -expression\iref{expr.cond}, the set is the union of the sets of -potential results of the second and third operands. -\item If $E$ is a comma expression\iref{expr.comma}, the set -contains the potential results of the right operand. -\item Otherwise, the set is empty. -\end{itemize} +The library defines a number of atomic operations\iref{atomics} and +operations on mutexes\iref{thread} that are specially identified as +synchronization operations. These operations play a special role in making +assignments in one thread visible to another. A synchronization operation on one +or more memory locations is either a consume operation, an acquire operation, a +release operation, or both an acquire and release operation. A synchronization +operation without an associated memory location is a fence and can be either an +acquire fence, a release fence, or both an acquire and release fence. In +addition, there are relaxed atomic operations, which are not synchronization +operations, and atomic read-modify-write operations, which have special +characteristics. \begin{note} -This set is a (possibly-empty) set of \grammarterm{id-expression}{s}, -each of which is either $E$ or a subexpression of $E$. -\begin{example} -In the following example, the set of potential results of the initializer -of \tcode{n} contains the first \tcode{S::x} subexpression, but not the second -\tcode{S::x} subexpression. -\begin{codeblock} -struct S { static const int x = 0; }; -const int &f(const int &r); -int n = b ? (1, S::x) // \tcode{S::x} is not odr-used here - : f(S::x); // \tcode{S::x} is odr-used here, so a definition is required -\end{codeblock} -\end{example} +For example, a call that acquires a mutex will +perform an acquire operation on the locations comprising the mutex. +Correspondingly, a call that releases the same mutex will perform a release +operation on those same locations. Informally, performing a release operation on +$A$ forces prior +\indextext{side effects}% +side effects on other memory locations to become visible +to other threads that later perform a consume or an acquire operation on +$A$. ``Relaxed'' atomic operations are not synchronization operations even +though, like synchronization operations, they cannot contribute to data races. \end{note} \pnum -A function is \defnx{named by}{function!named by expression or conversion} -an expression or conversion as follows: +All modifications to a particular atomic object $M$ occur in some +particular total order, called the \defn{modification order} of $M$. +\begin{note} +There is a separate order for each +atomic object. There is no requirement that these can be combined into a single +total order for all objects. In general this will be impossible since different +threads can observe modifications to different objects in inconsistent orders. +\end{note} + +\pnum +A \defn{release sequence} headed +by a release operation $A$ on an atomic object $M$ +is a maximal contiguous sub-sequence of +\indextext{side effects}% +side effects in the modification order of $M$, +where the first operation is $A$, and +every subsequent operation is an atomic read-modify-write operation. + +\pnum +Certain library calls \defn{synchronize with} other library calls performed by +another thread. For example, an atomic store-release synchronizes with a +load-acquire that takes its value from the store\iref{atomics.order}. +\begin{note} +Except in the specified cases, reading a later value does not +necessarily ensure visibility as described below. Such a requirement would +sometimes interfere with efficient implementation. +\end{note} +\begin{note} +The +specifications of the synchronization operations define when one reads the value +written by another. For atomic objects, the definition is clear. All operations +on a given mutex occur in a single total order. Each mutex acquisition ``reads +the value written'' by the last mutex release. +\end{note} + +\pnum +An evaluation $A$ \defn{carries a dependency} to an evaluation $B$ if \begin{itemize} \item - A function is named by an expression or conversion - if it is the selected member - of an overload set\iref{basic.lookup,over.match,over.over} - in an overload resolution performed - as part of forming that expression or conversion, - unless it is a pure virtual function and either - 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\iref{conv.func,expr.unary.op}, - calls to named functions\iref{expr.call}, - operator overloading\iref{over}, - user-defined conversions\iref{class.conv.fct}, - 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 or conversion - even if the call is actually elided by the implementation\iref{class.copy.elision}. +the value of $A$ is used as an operand of $B$, unless: +\begin{itemize} +\item +$B$ is an invocation of any specialization of +\tcode{std::kill_dependency}\iref{atomics.order}, or +\item +$A$ is the left operand of a built-in logical \logop{and} (\tcode{\&\&}, +see~\ref{expr.log.and}) or logical \logop{or} (\tcode{||}, see~\ref{expr.log.or}) +operator, or +\item +$A$ is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) +operator, or +\item +$A$ is the left operand of the built-in comma (\tcode{,}) +operator\iref{expr.comma}; \end{itemize} or +\item +$A$ writes a scalar object or bit-field $M$, $B$ reads the value +written by $A$ from $M$, and $A$ is sequenced before $B$, or +\item +for some evaluation $X$, $A$ carries a dependency to $X$, and +$X$ carries a dependency to $B$. +\end{itemize} +\begin{note} +``Carries a dependency to'' is a subset of ``is sequenced before'', +and is similarly strictly intra-thread. \end{note} + +\pnum +An evaluation $A$ is \defn{dependency-ordered before} an evaluation +$B$ if +\begin{itemize} \item - A deallocation function for a class - is named by a \grammarterm{new-expression} - if it is the single matching deallocation function - for the allocation function selected by overload resolution, - as specified in~\ref{expr.new}. +$A$ performs a release operation on an atomic object $M$, and, in +another thread, $B$ performs a consume operation on $M$ and reads +the value written by $A$, or + \item - A deallocation function for a class - 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}. +for some evaluation $X$, $A$ is dependency-ordered before $X$ and +$X$ carries a dependency to $B$. + \end{itemize} +\begin{note} +The relation ``is dependency-ordered before'' is analogous to +``synchronizes with'', but uses release/consume in place of release/acquire. +\end{note} \pnum -\label{term.odr.use}% -A variable is named by an expression -if the expression is an \grammarterm{id-expression} that denotes it. -A variable \tcode{x} that is named by a -potentially-evaluated expression $E$ -is \defnx{odr-used}{odr-use} by $E$ unless +An evaluation $A$ \defn{inter-thread happens before} an evaluation $B$ +if \begin{itemize} \item - \tcode{x} is a reference that is - usable in constant expressions\iref{expr.const}, or + $A$ synchronizes with $B$, or \item - \tcode{x} is a variable of non-reference type that is - usable in constant expressions and has no mutable subobjects, and - $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 + $A$ is dependency-ordered before $B$, or \item - \tcode{x} is a variable of non-reference type, and - $E$ is an element of the set of potential results - of a discarded-value expression\iref{expr.context} - to which the lvalue-to-rvalue conversion is not applied. + for some evaluation $X$ + \begin{itemize} + \item + $A$ synchronizes with $X$ and $X$ + is sequenced before $B$, or + \item + $A$ is sequenced before $X$ and $X$ + inter-thread happens before $B$, or + \item + $A$ inter-thread happens before $X$ and $X$ + inter-thread happens before $B$. + \end{itemize} \end{itemize} +\begin{note} +The ``inter-thread happens before'' relation describes arbitrary +concatenations of ``sequenced before'', ``synchronizes with'' and +``dependency-ordered before'' relationships, with two exceptions. The first +exception is that a concatenation never ends with +``dependency-ordered before'' followed by ``sequenced before''. The reason for +this limitation is that a consume operation participating in a +``dependency-ordered before'' relationship provides ordering only with respect +to operations to which this consume operation actually carries a dependency. The +reason that this limitation applies only to the end of such a concatenation is +that any subsequent release operation will provide the required ordering for a +prior consume operation. The second exception is that a concatenation never +consist entirely of ``sequenced before''. The reasons for this +limitation are (1) to permit ``inter-thread happens before'' to be transitively +closed and (2) the ``happens before'' relation, defined below, provides for +relationships consisting entirely of ``sequenced before''. +\end{note} \pnum -A structured binding is odr-used if it appears as a potentially-evaluated expression. +An evaluation $A$ \defn{happens before} an evaluation $B$ +(or, equivalently, $B$ \defn{happens after} $A$) if +\begin{itemize} +\item $A$ is sequenced before $B$, or +\item $A$ inter-thread happens before $B$. +\end{itemize} +The implementation shall ensure that no program execution demonstrates a cycle +in the ``happens before'' relation. +\begin{note} +This cycle would otherwise be +possible only through the use of consume operations. +\end{note} \pnum -\tcode{*\keyword{this}} is odr-used if \keyword{this} appears as a potentially-evaluated expression -(including as the result of any implicit transformation to -a class member access expression\iref{expr.prim.id.general}). +An evaluation $A$ \defn{simply happens before} an evaluation $B$ +if either +\begin{itemize} +\item $A$ is sequenced before $B$, or +\item $A$ synchronizes with $B$, or +\item $A$ simply happens before $X$ and +$X$ simply happens before $B$. +\end{itemize} +\begin{note} +In the absence of consume operations, +the happens before and simply happens before relations are identical. +\end{note} \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 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 -definition of the destructor of that class, or by being selected by the -lookup at the point of definition of a virtual -destructor\iref{class.dtor}. -\begin{footnote} -An implementation is not required -to call allocation and -deallocation functions from constructors or destructors; however, this -is a permissible implementation technique. -\end{footnote} - -\pnum -An assignment operator function in a class is odr-used by an -implicitly-defined -copy assignment or move assignment function for another class as specified -in~\ref{class.copy.assign}. -A constructor for a class is odr-used as specified -in~\ref{dcl.init}. A destructor for a class is odr-used if it is potentially -invoked\iref{class.dtor}. +An evaluation $A$ \defn{strongly happens before} +an evaluation $D$ if, either +\begin{itemize} +\item $A$ is sequenced before $D$, or +\item $A$ synchronizes with $D$, and +both $A$ and $D$ are +sequentially consistent atomic operations\iref{atomics.order}, or +\item there are evaluations $B$ and $C$ +such that $A$ is sequenced before $B$, +$B$ simply happens before $C$, and +$C$ is sequenced before $D$, or +\item there is an evaluation $B$ such that +$A$ strongly happens before $B$, and +$B$ strongly happens before $D$. +\end{itemize} +\begin{note} +Informally, if $A$ strongly happens before $B$, +then $A$ appears to be evaluated before $B$ +in all contexts. Strongly happens before excludes consume operations. +\end{note} \pnum -A local entity\iref{basic.pre} -is \defn{odr-usable} in a scope\iref{basic.scope.scope} if -\begin{itemize} -\item either the local entity is not \tcode{*\keyword{this}}, or -an enclosing class or non-lambda function parameter scope exists and, -if the innermost such scope is a function parameter scope, -it corresponds to a non-static member function, and -\item -for each intervening scope\iref{basic.scope.scope} -between the point at which the entity is introduced and the scope -(where \tcode{*\keyword{this}} is considered to be introduced -within the innermost enclosing class or non-lambda function definition scope), -either: +A \defnadjx{visible}{side effect}{side effects} $A$ on a scalar object or bit-field $M$ +with respect to a value computation $B$ of $M$ satisfies the +conditions: \begin{itemize} -\item the intervening scope is a block scope, or -\item the intervening scope is the function parameter scope of a \grammarterm{lambda-expression}, or -\item the intervening scope is the lambda scope of -a \grammarterm{lambda-expression} -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 scope. -\end{itemize} +\item $A$ happens before $B$ and +\item there is no other +\indextext{side effects}% +side effect $X$ to $M$ such that $A$ +happens before $X$ and $X$ happens before $B$. \end{itemize} -If a local entity is odr-used -in a scope in which it is not odr-usable, -the program is ill-formed. -\begin{example} -\begin{codeblock} -void f(int n) { - [] { 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 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} -\end{example} +The value of a non-atomic scalar object or bit-field $M$, as determined by +evaluation $B$, is the value stored by the +\indextext{side effects!visible}% +visible side effect $A$. +\begin{note} +If there is ambiguity about which side effect to a +non-atomic object or bit-field is visible, then the behavior is either +unspecified or undefined. +\end{note} +\begin{note} +This states that operations on +ordinary objects are not visibly reordered. This is not actually detectable +without data races, but is needed to ensure that data races, as defined +below, and with suitable restrictions on the use of atomics, correspond to data +races in a simple interleaved (sequentially consistent) execution. +\end{note} \pnum -\begin{example} -\begin{codeblock} -void g() { - constexpr int x = 1; - auto lambda = [] {}; // OK - lambda.operator()(); // OK, does not consider \tcode{x} at all - lambda.operator()(); // OK, does not odr-use \tcode{x} - lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable -} +The value of an +atomic object $M$, as determined by evaluation $B$, is the value +stored by some unspecified +side effect $A$ that modifies $M$, where $B$ does not happen +before $A$. +\begin{note} +The set of such side effects is also restricted by the rest of the rules +described here, and in particular, by the coherence requirements below. +\end{note} -void h() { - constexpr int x = 1; - auto lambda = [] { (T)x; }; // OK - lambda.operator()(); // OK, does not odr-use \tcode{x} - lambda.operator()(); // OK, does not odr-use \tcode{x} - lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable -} -\end{codeblock} -\end{example} +\pnum +\indextext{coherence!write-write}% +If an operation $A$ that modifies an atomic object $M$ happens before +an operation $B$ that modifies $M$, then $A$ is earlier +than $B$ in the modification order of $M$. +\begin{note} +This requirement is known as write-write coherence. +\end{note} \pnum -Every program shall contain at least one definition of every -function or variable that is odr-used in that program -outside of a discarded statement\iref{stmt.if}; no diagnostic required. -The definition can appear explicitly in the program, it can be found in -the standard or a user-defined library, or (when appropriate) it is -implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor}, -\ref{class.dtor}, and \ref{class.copy.assign}). -\begin{example} -\begin{codeblock} -auto f() { - struct A {}; - return A{}; -} -decltype(f()) g(); -auto x = g(); -\end{codeblock} -A program containing this translation unit is ill-formed -because \tcode{g} is odr-used but not defined, -and cannot be defined in any other translation unit -because the local class \tcode{A} cannot be named outside this -translation unit. -\end{example} +\indextext{coherence!read-read}% +If a +\indextext{value computation}% +value computation $A$ of an atomic object $M$ happens before a +value computation $B$ of $M$, and $A$ takes its value from a side +effect $X$ on $M$, then the value computed by $B$ is either +the value stored by $X$ or the value stored by a +\indextext{side effects}% +side effect $Y$ on $M$, +where $Y$ follows $X$ in the modification order of $M$. +\begin{note} +This requirement is known as read-read coherence. +\end{note} \pnum -A \defn{definition domain} is -a \grammarterm{private-module-fragment} or -the portion of a translation unit -excluding its \grammarterm{private-module-fragment} (if any). -A definition of an inline function or variable shall be reachable -from the end of every definition domain -in which it is odr-used outside of a discarded statement. +\indextext{coherence!read-write}% +If a +\indextext{value computation}% +value computation $A$ of an atomic object $M$ happens before an +operation $B$ that modifies $M$, then $A$ takes its value from a side +effect $X$ on $M$, where $X$ precedes $B$ in the +modification order of $M$. +\begin{note} +This requirement is known as +read-write coherence. +\end{note} \pnum -\indextext{type!incomplete}% -A definition of a class shall be reachable in every context in which -the class is used in a way that requires the class type to be complete. -\begin{example} -The following complete translation unit is well-formed, -even though it never defines \tcode{X}: -\begin{codeblock} -struct X; // declare \tcode{X} as a struct type -struct X* x1; // use \tcode{X} in pointer formation -X* x2; // use \tcode{X} in pointer formation -\end{codeblock} -\end{example} +\indextext{coherence!write-read}% +If a +\indextext{side effects}% +side effect $X$ on an atomic object $M$ happens before a value +computation $B$ of $M$, then the evaluation $B$ takes its +value from $X$ or from a +\indextext{side effects}% +side effect $Y$ that follows $X$ in the modification order of $M$. \begin{note} -The rules for declarations and expressions -describe in which contexts complete class types are required. A class -type \tcode{T} must be complete if -\begin{itemize} -\item an object of type \tcode{T} is defined\iref{basic.def}, or -\item a non-static class data member of type \tcode{T} is -declared\iref{class.mem}, or -\item \tcode{T} is used as the allocated type or array element type in a -\grammarterm{new-expression}\iref{expr.new}, or -\item an lvalue-to-rvalue conversion is applied to -a glvalue referring -to an object of type \tcode{T}\iref{conv.lval}, or -\item an expression is converted (either implicitly or explicitly) to -type \tcode{T}\iref{conv,expr.type.conv, -expr.dynamic.cast,expr.static.cast,expr.cast}, or -\item an expression that is not a null pointer constant, and has type -other than \cv{}~\tcode{\keyword{void}*}, is converted to the type pointer to \tcode{T} -or reference to \tcode{T} using a standard conversion\iref{conv}, -a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or -a \keyword{static_cast}\iref{expr.static.cast}, or -\item a class member access operator is applied to an expression of type -\tcode{T}\iref{expr.ref}, or -\item the \keyword{typeid} operator\iref{expr.typeid} or the -\keyword{sizeof} operator\iref{expr.sizeof} is applied to an operand of -type \tcode{T}, or -\item a function with a return type or argument type of type \tcode{T} -is defined\iref{basic.def} or called\iref{expr.call}, or -\item a class with a base class of type \tcode{T} is -defined\iref{class.derived}, or -\item an lvalue of type \tcode{T} is assigned to\iref{expr.ass}, or -\item the type \tcode{T} is the subject of an -\keyword{alignof} expression\iref{expr.alignof}, or -\item an \grammarterm{exception-declaration} has type \tcode{T}, reference to -\tcode{T}, or pointer to \tcode{T}\iref{except.handle}. -\end{itemize} +This requirement is known as write-read coherence. \end{note} \pnum -For any definable item \tcode{D} with definitions in multiple translation units, +\begin{note} +The four preceding coherence requirements effectively disallow +compiler reordering of atomic operations to a single object, even if both +operations are relaxed loads. This effectively makes the cache coherence +guarantee provided by most hardware available to \Cpp{} atomic operations. +\end{note} + +\pnum +\begin{note} +The value observed by a load of an atomic depends on the ``happens +before'' relation, which depends on the values observed by loads of atomics. +The intended reading is that there must exist an +association of atomic loads with modifications they observe that, together with +suitably chosen modification orders and the ``happens before'' relation derived +as described above, satisfy the resulting constraints as imposed here. +\end{note} + +\pnum +Two actions are \defn{potentially concurrent} if \begin{itemize} -\item -if \tcode{D} is a non-inline non-templated function or variable, or -\item -if the definitions in different translation units -do not satisfy the following requirements, -\end{itemize} -the program is ill-formed; -a diagnostic is required only -if the definable item is attached to a named module and -a prior definition is reachable at the point where a later definition occurs. -Given such an item, -for all definitions of \tcode{D}, or, -if \tcode{D} is an unnamed enumeration, -for all definitions of \tcode{D} that are reachable at any given program point, -the following requirements shall be satisfied. -\begin{itemize} -\item Each such definition -shall not be attached to a named module\iref{module.unit}. -\item Each such definition shall consist of -the same sequence of tokens, -where the definition of a closure type -is considered to consist of the sequence of tokens of -the corresponding \grammarterm{lambda-expression}. -\item In each such definition, corresponding names, looked up -according to~\ref{basic.lookup}, shall refer to the same entity, after -overload resolution\iref{over.match} and after matching of partial -template specialization\iref{temp.over}, except that a name can refer to -\begin{itemize} -\item -a non-volatile const object with internal or no linkage if the object -\begin{itemize} -\item has the same literal type in all definitions of \tcode{D}, -\item is initialized with a constant expression\iref{expr.const}, -\item is not odr-used in any definition of \tcode{D}, and -\item has the same value in all definitions of \tcode{D}, -\end{itemize} -or -\item -a reference with internal or no linkage -initialized with a constant expression such that -the reference refers to the same entity in all definitions of \tcode{D}. +\item they are performed by different threads, or +\item they are unsequenced, at least one is performed by a signal handler, and +they are not both performed by the same signal handler invocation. \end{itemize} +The execution of a program contains a \defn{data race} if it contains two +potentially concurrent conflicting actions, at least one of which is not atomic, +and neither happens before the other, +except for the special case for signal handlers described below. +Any such data race results in undefined +behavior. +\begin{note} +It can be shown that programs that correctly use mutexes +and \tcode{memory_order::seq_cst} operations to prevent all data races and use no +other synchronization operations behave as if the operations executed by their +constituent threads were simply interleaved, with each +\indextext{value computation}% +value computation of an +object being taken from the last +\indextext{side effects}% +side effect on that object in that +interleaving. This is normally referred to as ``sequential consistency''. +However, this applies only to data-race-free programs, and data-race-free +programs cannot observe most program transformations that do not change +single-threaded program semantics. In fact, most single-threaded program +transformations remain possible, since any program that behaves +differently as a result has undefined behavior. +\end{note} -\item In each such definition, except within -the default arguments and default template arguments of \tcode{D}, -corresponding \grammarterm{lambda-expression}{s} shall have -the same closure type (see below). - -\item In each such definition, corresponding entities shall have the -same language linkage. +\pnum +Two accesses to the same object of type \tcode{\keyword{volatile} std::sig_atomic_t} do not +result in a data race if both occur in the same thread, even if one or more +occurs in a signal handler. For each signal handler invocation, evaluations +performed by the thread invoking a signal handler can be divided into two +groups $A$ and $B$, such that no evaluations in +$B$ happen before evaluations in $A$, and the +evaluations of such \tcode{\keyword{volatile} std::sig_atomic_t} objects take values as though +all evaluations in $A$ happened before the execution of the signal +handler and the execution of the signal handler happened before all evaluations +in $B$. -\item In each such definition, -const objects with static or thread storage duration -shall be constant-initialized if -the object is constant-initialized in any such definition. +\pnum +\begin{note} +Compiler transformations that introduce assignments to a potentially +shared memory location that would not be modified by the abstract machine are +generally precluded by this document, since such an assignment might overwrite +another assignment by a different thread in cases in which an abstract machine +execution would not have encountered a data race. This includes implementations +of data member assignment that overwrite adjacent members in separate memory +locations. Reordering of atomic loads in cases in which the atomics in question +might alias is also generally precluded, since this could violate the coherence +rules. +\end{note} -\item In each such definition, -corresponding manifestly constant-evaluated expressions -that are not value-dependent -shall have the same value\iref{expr.const,temp.dep.constexpr}. +\pnum +\begin{note} +It is possible that transformations that introduce a speculative read of a potentially +shared memory location do not preserve the semantics of the \Cpp{} program as +defined in this document, since they potentially introduce a data race. However, +they are typically valid in the context of an optimizing compiler that targets a +specific machine with well-defined semantics for data races. They would be +invalid for a hypothetical machine that is not tolerant of races or provides +hardware race detection. +\end{note} -\item In each such definition, the overloaded operators referred -to, the implicit calls to conversion functions, constructors, operator -new functions and operator delete functions, shall refer to the same -function. +\rSec3[intro.progress]{Forward progress} -\item In each such definition, -a default argument used by an (implicit or explicit) function call or -a default template argument used by an (implicit or explicit) -\grammarterm{template-id} or \grammarterm{simple-template-id} -is treated as if its token sequence -were present in the definition of \tcode{D}; -that is, the default argument or default template argument -is subject to the requirements described in this paragraph (recursively). +\pnum +The implementation may assume that any thread will eventually do one of the +following: +\begin{itemize} +\item terminate, +\item invoke the function \tcode{std::this_thread::yield}\iref{thread.thread.this}, +\item make a call to a library I/O function, +\item perform an access through a volatile glvalue, +\item perform a synchronization operation or an atomic operation, or +\item continue execution of a trivial infinite loop\iref{stmt.iter.general}. \end{itemize} +\begin{note} +This is intended to allow compiler transformations +such as removal, merging, and reordering of empty loops, +even when termination cannot be proven. +An affordance is made for trivial infinite loops, +which cannot be removed nor reordered. +\end{note} \pnum -For the purposes of the preceding requirements: - +Executions of atomic functions +that are either defined to be lock-free\iref{atomics.flag} +or indicated as lock-free\iref{atomics.lockfree} +are \defnx{lock-free executions}{lock-free execution}. \begin{itemize} -\item If \tcode{D} is a class with an implicitly-declared -constructor\iref{class.default.ctor,class.copy.ctor}, -it is as if the constructor was -implicitly defined in every translation unit where it is odr-used, and the -implicit definition in every translation unit shall call the same -constructor for a subobject of \tcode{D}. -\begin{example} -\begin{codeblock} -// translation unit 1: -struct X { - X(int, int); - X(int, int, int); -}; -X::X(int, int = 0) { } -class D { - X x = 0; -}; -D d1; // \tcode{X(int, int)} called by \tcode{D()} - -// translation unit 2: -struct X { - X(int, int); - X(int, int, int); -}; -X::X(int, int = 0, int = 0) { } -class D { - X x = 0; -}; -D d2; // \tcode{X(int, int, int)} called by \tcode{D()}; - // \tcode{D()}'s implicit definition violates the ODR -\end{codeblock} -\end{example} - -\item If \tcode{D} is a class with -a defaulted three-way comparison operator function\iref{class.spaceship}, -it is as if the operator was -implicitly defined in every translation unit where it is odr-used, and the -implicit definition in every translation unit shall call the same -comparison operators for each subobject of \tcode{D}. - \item -If \tcode{D} is a template and is defined in more than one -translation unit, the requirements -apply both to names from the template's enclosing scope used in the -template definition, and also to dependent names at -the point of instantiation\iref{temp.dep}. + If there is only one thread that is not blocked\iref{defns.block} + in a standard library function, + a lock-free execution in that thread shall complete. + \begin{note} + Concurrently executing threads + might prevent progress of a lock-free execution. + For example, + this situation can occur + with load-locked store-conditional implementations. + This property is sometimes termed obstruction-free. + \end{note} +\item + When one or more lock-free executions run concurrently, + at least one should complete. + \begin{note} + It is difficult for some implementations + to provide absolute guarantees to this effect, + since repeated and particularly inopportune interference + from other threads + could prevent forward progress, + e.g., + by repeatedly stealing a cache line + for unrelated purposes + between load-locked and store-conditional instructions. + For implementations that follow this recommendation and + ensure that such effects cannot indefinitely delay progress + under expected operating conditions, + such anomalies + can therefore safely be ignored by programmers. + Outside this document, + this property is sometimes termed lock-free. + \end{note} \end{itemize} \pnum -These requirements also apply to corresponding entities -defined within each definition of \tcode{D} -(including the closure types of \grammarterm{lambda-expression}{s}, -but excluding entities defined within default arguments or -default template arguments of either \tcode{D} or -an entity not defined within \tcode{D}). -For each such entity and for \tcode{D} itself, -the behavior is as if there is a single entity with a single definition, -including in the application of these requirements to other entities. -\begin{note} -The entity is still declared in multiple translation units, and \ref{basic.link} -still applies to these declarations. In particular, -\grammarterm{lambda-expression}{s}\iref{expr.prim.lambda} -appearing in the type of \tcode{D} can result -in the different declarations having distinct types, and -\grammarterm{lambda-expression}{s} appearing in a default argument of \tcode{D} -might still denote different types in different translation units. -\end{note} +During the execution of a thread of execution, each of the following is termed +an \defn{execution step}: +\begin{itemize} +\item termination of the thread of execution, +\item performing an access through a volatile glvalue, or +\item completion of a call to a library I/O function, a + synchronization operation, or an atomic operation. +\end{itemize} \pnum +An invocation of a standard library function that blocks\iref{defns.block} +is considered to continuously execute execution steps while waiting for the +condition that it blocks on to be satisfied. \begin{example} -\begin{codeblock} -inline void f(bool cond, void (*p)()) { - if (cond) f(false, []{}); -} -inline void g(bool cond, void (*p)() = []{}) { - if (cond) g(false); -} -struct X { - void h(bool cond, void (*p)() = []{}) { - if (cond) h(false); - } -}; -\end{codeblock} - -If the definition of \tcode{f} appears in multiple translation units, -the behavior of the program is as if -there is only one definition of \tcode{f}. -If the definition of \tcode{g} appears in multiple translation units, -the program is ill-formed (no diagnostic required) because -each such definition uses a default argument that -refers to a distinct \grammarterm{lambda-expression} closure type. -The definition of \tcode{X} can appear -in multiple translation units of a valid program; -the \grammarterm{lambda-expression}{s} defined within -the default argument of \tcode{X::h} within the definition of \tcode{X} -denote the same closure type in each translation unit. +A library I/O function that blocks until the I/O operation is complete can +be considered to continuously check whether the operation is complete. Each +such check consists of one or more execution steps, for example using +observable behavior of the abstract machine. \end{example} \pnum -If, at any point in the program, -there is more than one -reachable unnamed enumeration definition in the same scope -that have the same first enumerator name and -do not have typedef names for linkage purposes\iref{dcl.enum}, -those unnamed enumeration types shall be the same; no diagnostic required. -\indextext{one-definition rule|)} - -\rSec1[basic.scope]{Scope}% -\indextext{scope|(} - -\rSec2[basic.scope.scope]{General} +\begin{note} +Because of this and the preceding requirement regarding what threads of execution +have to perform eventually, it follows that no thread of execution can execute +forever without an execution step occurring. +\end{note} \pnum -The declarations in a program appear in a number of \defnx{scopes}{scope} -that are in general discontiguous. -The \defnadj{global}{scope} contains the entire program; -every other scope $S$ is introduced by a -declaration, -\grammarterm{parameter-declaration-clause}, -\grammarterm{statement}, or \grammarterm{handler} -(as described in the following subclauses of \ref{basic.scope}) -appearing in another scope which thereby contains $S$. -An \defnadj{enclosing}{scope} at a program point is any scope that contains it; -the smallest such scope is said to be the \defnadj{immediate}{scope} -at that point. -A scope \defnx{intervenes}{scope!intervene} -between a program point $P$ and a scope $S$ -(that does not contain $P$) if it is or contains $S$ but does not contain $P$. +A thread of execution \defnx{makes progress}{make progress!thread} +when an execution step occurs or a +lock-free execution does not complete because there are other concurrent threads +that are not blocked in a standard library function (see above). \pnum -Unless otherwise specified: -\begin{itemize} -\item -The smallest scope that contains a scope $S$ is -the \defnadj{parent}{scope} of $S$. -\item -No two declarations (re)introduce the same entity. -\item -A declaration \defnx{inhabits}{scope!inhabit} -the immediate scope at its locus\iref{basic.scope.pdecl}. -\item -A declaration's \defnadj{target}{scope} is the scope it inhabits. -\item -Any names (re)introduced by a declaration are \defnx{bound}{name!bound} to it -in its target scope. -\end{itemize} -An entity \defnx{belongs}{entity!belong} to a scope $S$ -if $S$ is the target scope of a declaration of the entity. +\indextext{forward progress guarantees!concurrent}% +For a thread of execution providing \defn{concurrent forward progress guarantees}, +the implementation ensures that the thread will eventually make progress for as +long as it has not terminated. \begin{note} -Special cases include that: -\begin{itemize} -\item -Template parameter scopes are parents -only to other template parameter scopes\iref{basic.scope.temp}. -\item -Corresponding declarations with appropriate linkage -declare the same entity\iref{basic.link}. -\item -The declaration in a \grammarterm{template-declaration} -inhabits the same scope as the \grammarterm{template-declaration}. -\item -Friend declarations and -declarations of template specializations do not bind names\iref{dcl.meaning}; -those with qualified names target a specified scope, and -other friend declarations and -certain \grammarterm{elaborated-type-specifier}s\iref{dcl.type.elab} -target a larger enclosing scope. -\item -Block-scope extern declarations target a larger enclosing scope -but bind a name in their immediate scope. -\item -The names of unscoped enumerators are bound -in the two innermost enclosing scopes\iref{dcl.enum}. -\item -A class's name is also bound in its own scope\iref{class.pre}. -\item -The names of the members of an anonymous union are bound in -the union's parent scope\iref{class.union.anon}. -\end{itemize} +This applies regardless of whether or not other threads of execution (if any) +have been or are making progress. To eventually fulfill this requirement means that +this will happen in an unspecified but finite amount of time. \end{note} \pnum -Two non-static member functions have -\defnadjx{corresponding}{object parameters}{object parameter} if -\begin{itemize} -\item -exactly one is an implicit object member function -with no \grammarterm{ref-qualifier} and -the types of their object parameters\iref{dcl.fct}, -after removing references, -are the same, or -\item -their object parameters have the same type. -\end{itemize} -\indextext{template!function!corresponding object parameter}% -Two non-static member function templates have -\defnadjx{corresponding}{object parameters}{object parameter} if -\begin{itemize} -\item -exactly one is an implicit object member function -with no \grammarterm{ref-qualifier} and -the types of their object parameters, -after removing any references, -are equivalent, or -\item -the types of their object parameters are equivalent. -\end{itemize} -\indextext{template!function!corresponding signature}% -Two function templates have -\defnadjx{corresponding}{signatures}{signature} if -their \grammarterm{template-parameter-list}{s} -have the same length, -their corresponding \grammarterm{template-parameter}{s} are equivalent, -they have equivalent non-object-parameter-type-lists and return types (if any), and, -if both are non-static members, they have corresponding object parameters. +It is \impldef{whether the thread that executes \tcode{main} and the threads created +by \tcode{std::thread} or \tcode{std::jthread} provide concurrent forward progress guarantees} whether the +implementation-created thread of execution that executes +\tcode{main}\iref{basic.start.main} and the threads of execution created by +\tcode{std::thread}\iref{thread.thread.class} +or \tcode{std::jthread}\iref{thread.jthread.class} +provide concurrent forward progress guarantees. +General-purpose implementations should provide these guarantees. + +\pnum +\indextext{forward progress guarantees!parallel}% +For a thread of execution providing \defn{parallel forward progress guarantees}, +the implementation is not required to ensure that the thread will eventually make +progress if it has not yet executed any execution step; once this thread has +executed a step, it provides concurrent forward progress guarantees. \pnum -Two declarations \defn{correspond} -if they (re)introduce the same name, -both declare constructors, or -both declare destructors, -unless -\begin{itemize} -\item -either is a \grammarterm{using-declarator}, or -\item -one declares a type (not a \grammarterm{typedef-name}) and the other declares a -variable, -non-static data member other than of an anonymous union\iref{class.union.anon}, -enumerator, -function, or -function template, or -\item -each declares a function or function template -and they do not declare corresponding overloads. -\end{itemize} -Two function or function template declarations declare -\defn{corresponding overloads} if -\begin{itemize} -\item -both declare functions with the same non-object-parameter-type-list, -\begin{footnote} -An implicit object parameter\iref{over.match.funcs} -is not part of the parameter-type-list. -\end{footnote} -equivalent\iref{temp.over.link} trailing \grammarterm{requires-clause}s -(if any, except as specified in \ref{temp.friend}), and, -if both are non-static members, -they have corresponding object parameters, or -\item -both declare function templates with corresponding signatures and equivalent -\grammarterm{template-head}s and -trailing \grammarterm{requires-clause}s (if any). -\end{itemize} \begin{note} -Declarations can correspond even if neither binds a name. -\begin{example} -\begin{codeblock} -struct A { - friend void f(); // \#1 -}; -struct B { - friend void f() {} // corresponds to, and defines, \#1 -}; -\end{codeblock} -\end{example} +This does not specify a requirement for when to start this thread of execution, +which will typically be specified by the entity that creates this thread of +execution. For example, a thread of execution that provides concurrent forward +progress guarantees and executes tasks from a set of tasks in an arbitrary order, +one after the other, satisfies the requirements of parallel forward progress for +these tasks. \end{note} -\begin{example} -\begin{codeblock} -typedef int Int; -enum E : int { a }; -void f(int); // \#1 -void f(Int) {} // defines \#1 -void f(E) {} // OK, another overload -struct X { - static void f(); - void f() const; // error: redeclaration - void g(); - void g() const; // OK - void g() &; // error: redeclaration +\pnum +\indextext{forward progress guarantees!weakly parallel}% +For a thread of execution providing \defn{weakly parallel forward progress +guarantees}, the implementation does not ensure that the thread will eventually +make progress. - void h(this X&, int); - void h(int) &&; // OK, another overload - void j(this const X&); - void j() const &; // error: redeclaration - void k(); - void k(this X&); // error: redeclaration -}; -\end{codeblock} -\end{example} +\pnum +\begin{note} +Threads of execution providing weakly parallel forward progress guarantees cannot +be expected to make progress regardless of whether other threads make progress or +not; however, blocking with forward progress guarantee delegation, as defined below, +can be used to ensure that such threads of execution make progress eventually. +\end{note} \pnum -A declaration is \defnx{name-independent}{declaration!name-independent} -if its name is \tcode{_} (\unicode{005f}{low line}) and it declares -\begin{itemize} -\item -a variable with automatic storage duration, -\item -a structured binding -%FIXME: "and" is strange below; maybe reword to something like: -%FIXME: "that has no \grammarterm{storage-class-specifier} and -%FIXME: that is not inhabiting a namespace scope," -with no \grammarterm{storage-class-specifier} and -not inhabiting a namespace scope, -\item -the variable introduced by an \grammarterm{init-capture}, or -\item -%FIXME: "of" is strange below; remove it? -a non-static data member of other than an anonymous union. -\end{itemize} - -\recommended -Implementations should not emit a warning -that a name-independent declaration is used or unused. - -\pnum -\indextext{declaration!potentially conflict}% -Two declarations \defn{potentially conflict} -if they correspond and -cause their shared name to denote different entities\iref{basic.link}. -The program is ill-formed -if, in any scope, a name is bound to two declarations $A$ and $B$ -that potentially conflict and $A$ precedes $B$\iref{basic.lookup}, -unless $B$ is name-independent. -\begin{note} -An \grammarterm{id-expression} that names a unique name-independent declaration -is usable until an additional declaration of the same name -is introduced in the same scope\iref{basic.lookup.general}. -\end{note} +Concurrent forward progress guarantees are stronger than parallel forward progress +guarantees, which in turn are stronger than weakly parallel forward progress +guarantees. \begin{note} -Overload resolution can consider potentially conflicting declarations -found in multiple scopes -(e.g., via \grammarterm{using-directive}s or for operator functions), -in which case it is often ambiguous. +For example, some kinds of synchronization between threads of execution might only +make progress if the respective threads of execution provide parallel forward progress +guarantees, but will fail to make progress under weakly parallel guarantees. \end{note} -\begin{example} -\begin{codeblock} -void f() { - int x,y; - void x(); // error: different entity for \tcode{x} - int y; // error: redefinition -} -enum { f }; // error: different entity for \tcode{::f} -namespace A {} -namespace B = A; -namespace B = A; // OK, no effect -namespace B = B; // OK, no effect -namespace A = B; // OK, no effect -namespace B {} // error: different entity for \tcode{B} - -void g() { - int _; - _ = 0; // OK - int _; // OK, name-independent declaration - _ = 0; // error: two non-function declarations in the lookup set -} -void h () { - int _; // \#1 - _ ++; // OK - static int _; // error: conflicts with \#1 because static variables are not name-independent -} -\end{codeblock} -\end{example} \pnum -\indextext{declaration!nominable}% -A declaration is \defn{nominable} -in a class, class template, or namespace $E$ at a point $P$ if -it precedes $P$, -it does not inhabit a block scope, and -its target scope is the scope associated with $E$ or, -if $E$ is a namespace, -any element of the inline namespace set of $E$\iref{namespace.def}. -\begin{example} -\begin{codeblock} -namespace A { - void f() {void g();} - inline namespace B { - struct S { - friend void h(); - static int i; - }; - } -} -\end{codeblock} -At the end of this example, -the declarations of \tcode{f}, \tcode{B}, \tcode{S}, and \tcode{h} -are nominable in \tcode{A}, but those of \tcode{g} and \tcode{i} are not. -\end{example} +\indextext{forward progress guarantees!delegation of}% +When a thread of execution $P$ is specified to +\defnx{block with forward progress guarantee delegation} +{block (execution)!with forward progress guarantee delegation} +on the completion of a set $S$ of threads of execution, +then throughout the whole time of $P$ being blocked on $S$, +the implementation shall ensure that the forward progress guarantees +provided by at least one thread of execution in $S$ +is at least as strong as $P$'s forward progress guarantees. +\begin{note} +It is unspecified which thread or threads of execution in $S$ are chosen +and for which number of execution steps. The strengthening is not permanent and +not necessarily in place for the rest of the lifetime of the affected thread of +execution. As long as $P$ is blocked, the implementation has to eventually +select and potentially strengthen a thread of execution in $S$. +\end{note} +Once a thread of execution in $S$ terminates, it is removed from $S$. +Once $S$ is empty, $P$ is unblocked. \pnum -When instantiating a templated entity\iref{temp.pre}, -any scope $S$ introduced by any part of the template definition is considered -to be introduced by the instantiated entity and -to contain the instantiations of any declarations that inhabit $S$. - -\rSec2[basic.scope.pdecl]{Point of declaration} - -\indextext{declaration!point of|see{locus}}% -\indextext{scope!declarations and|see{locus}}% -\indextext{locus|(}% +\begin{note} +A thread of execution $B$ thus can temporarily provide an effectively +stronger forward progress guarantee for a certain amount of time, due to a +second thread of execution $A$ being blocked on it with forward +progress guarantee delegation. In turn, if $B$ then blocks with +forward progress guarantee delegation on $C$, this can also temporarily +provide a stronger forward progress guarantee to $C$. +\end{note} \pnum -\indextext{declaration!locus|see{locus}}% -The \defn{locus} of a declaration\iref{basic.pre} that is a declarator -is immediately after the complete declarator\iref{dcl.decl}. -\begin{example} -\begin{codeblock} -unsigned char x = 12; -{ unsigned char x = x; } -\end{codeblock} -Here, the initialization of the second \tcode{x} has undefined behavior, -because the initializer accesses the second \tcode{x} -outside its lifetime\iref{basic.life}. -\end{example} +\begin{note} +If all threads of execution in $S$ finish executing (e.g., they terminate +and do not use blocking synchronization incorrectly), then $P$'s execution +of the operation that blocks with forward progress guarantee delegation will not +result in $P$'s progress guarantee being effectively weakened. +\end{note} \pnum \begin{note} -\indextext{name hiding}% -A name from an outer scope remains visible up to -the locus of the declaration that hides it. -\begin{example} -\begin{codeblock} -const int i = 2; -{ int i[i]; } -\end{codeblock} -declares a block-scope array of two integers. -\end{example} +This does not remove any constraints regarding blocking synchronization for +threads of execution providing parallel or weakly parallel forward progress +guarantees because the implementation is not required to strengthen a particular +thread of execution whose too-weak progress guarantee is preventing overall progress. \end{note} \pnum -The locus of a \grammarterm{class-specifier} is immediately after -the \grammarterm{identifier} or \grammarterm{simple-template-id} (if any) -in its \grammarterm{class-head}\iref{class.pre}. -The locus of an \grammarterm{enum-specifier} -is immediately after -its \grammarterm{enum-head}; -the locus of an \grammarterm{opaque-enum-declaration} -is immediately after it\iref{dcl.enum}. -%FIXME: What's "it" below? What's "it" above? -The locus of an \grammarterm{alias-declaration} is immediately after it. +An implementation should ensure that the last value (in modification order) +assigned by an atomic or synchronization operation will become visible to all +other threads in a finite period of time.% +\indextext{atomic!operation|)}% +\indextext{threads!multiple|)} -\pnum -The locus of a \grammarterm{using-declarator} -that does not name a constructor -is immediately after the \grammarterm{using-declarator}\iref{namespace.udecl}. +\rSec2[basic.start]{Start and termination} -\pnum -The locus of an \grammarterm{enumerator-definition} is immediately after it. -\begin{example} -\begin{codeblock} -const int x = 12; -{ enum { x = x }; } -\end{codeblock} -Here, the enumerator \tcode{x} is initialized with the value of the -constant \tcode{x}, namely 12. -\end{example} +\rSec3[basic.start.main]{\tcode{main} function} +\indextext{\idxcode{main} function|(} \pnum +\indextext{program!startup|(}% +A program shall contain exactly one function called \tcode{main} +that belongs to the global scope. +Executing a program starts a main thread of execution\iref{intro.multithread,thread.threads} +in which the \tcode{main} function is invoked. +\indextext{implementation!freestanding}% +It is \impldef{defining \tcode{main} in freestanding environment} +whether a program in a freestanding environment is required to define a \tcode{main} +function. \begin{note} -\indextext{type!incomplete}% -After the declaration of a class member, -the member name can be found in the scope of its class -even if the class is an incomplete class. -\begin{example} -\begin{codeblock} -struct X { - enum E { z = 16 }; - int b[X::z]; // OK -}; -\end{codeblock} -\end{example} +In a freestanding environment, startup and termination is +\impldef{startup and termination in freestanding environment}; startup contains the +execution of constructors for non-local objects with static storage duration; +termination contains the execution of destructors for objects with static storage +duration. \end{note} \pnum -The locus of an \grammarterm{elaborated-type-specifier} -that is a declaration\iref{dcl.type.elab} is immediately after it. +An implementation shall not predefine the \tcode{main} function. +Its type shall have \Cpp{} language linkage +and it shall have a declared return type of type +\keyword{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. +\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} +\end{itemize} +\indextext{\idxcode{argc}}% +\indextext{\idxcode{argv}}% +as the type of \tcode{main}\iref{dcl.fct}. +\indextext{\idxcode{main} function!parameters to}% +\indextext{environment!program}% +In the latter form, for purposes of exposition, the first function +parameter is called \tcode{argc} and the second function parameter is +called \tcode{argv}, where \tcode{argc} shall be the number of +arguments passed to the program from the environment in which the +program is run. If +\tcode{argc} is nonzero these arguments shall be supplied in +\tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial +characters of null-terminated multibyte strings (\ntmbs{}s)\iref{multibyte.strings} +and \tcode{argv[0]} shall be the pointer to +the initial character of an \ntmbs{} that represents the name used to +invoke the program or \tcode{""}. The value of \tcode{argc} shall be +non-negative. The value of \tcode{argv[argc]} shall be 0. + +\recommended +Any further (optional) parameters should be added after \tcode{argv}. \pnum -The locus of an injected-class-name declaration\iref{class.pre} -is immediately following the opening brace of the class definition. +The function \tcode{main} shall not be named by an expression. +\indextext{\idxcode{main} function!implementation-defined linkage of}% +The linkage\iref{basic.link} of \tcode{main} is +\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as +deleted or that declares \tcode{main} to be +\keyword{inline}, \keyword{static}, \keyword{constexpr}, or \keyword{consteval} is ill-formed. +The function \tcode{main} shall not be a coroutine\iref{dcl.fct.def.coroutine}. +The \tcode{main} function shall not be declared with a +\grammarterm{linkage-specification}\iref{dcl.link}. +A program that declares +\begin{itemize} +\item +a variable \tcode{main} that belongs to the global scope, or +\item +a function \tcode{main} that belongs to the global scope and +is attached to a named module, or +\item +a function template \tcode{main} that belongs to the global scope, or +\item +an entity named \tcode{main} +with C language linkage (in any namespace) +\end{itemize} +is ill-formed. +The name \tcode{main} is +not otherwise reserved. +\begin{example} +Member functions, classes, and +enumerations can be called \tcode{main}, as can entities in other +namespaces. +\end{example} \pnum -The locus of the implicit declaration of -a function-local predefined variable\iref{dcl.fct.def.general} -is immediately before -the \grammarterm{function-body} of its function's definition. +\indextext{\idxcode{exit}}% +\indexlibraryglobal{exit}% +\indextext{termination!program}% +Terminating the program +without leaving the current block (e.g., by calling the function +\tcode{std::exit(int)}\iref{support.start.term}) does not destroy any +objects with automatic storage duration\iref{class.dtor}. If +\tcode{std::exit} is invoked during the destruction of +an object with static or thread storage duration, the program has undefined +behavior. \pnum -The locus of the declaration of a structured binding\iref{dcl.struct.bind} -is immediately after -the \grammarterm{identifier-list} of the structured binding declaration. +\indextext{termination!program}% +\indextext{\idxcode{main} function!return from}% +A \keyword{return} statement\iref{stmt.return} in \tcode{main} has the effect of leaving the main +function (destroying any objects with automatic storage duration) and +calling \tcode{std::exit} with the return value as the argument. +If control flows off the end of +the \grammarterm{compound-statement} of \tcode{main}, +the effect is equivalent to a \keyword{return} with operand \tcode{0} +(see also \ref{except.handle}). +\indextext{\idxcode{main} function|)} -\pnum -The locus of a \grammarterm{for-range-declaration} -of a range-based \keyword{for} statement\iref{stmt.ranged} -is immediately after the \grammarterm{for-range-initializer}. +\rSec3[basic.start.static]{Static initialization} \pnum -The locus of a \grammarterm{template-parameter} is immediately after it. -\begin{example} -\begin{codeblock} -typedef unsigned char T; -template struct A { }; -\end{codeblock} -\end{example} +\indextext{initialization}% +\indextext{initialization!static and thread}% +Variables with static storage duration +are initialized as a consequence of program initiation. Variables with +thread storage duration are initialized as a consequence of thread execution. +Within each of these phases of initiation, initialization occurs as follows. \pnum -The locus of a \grammarterm{concept-definition} -is immediately after its \grammarterm{concept-name}\iref{temp.concept}. +\indextext{initialization!constant}% +\defnx{Constant initialization}{constant initialization} is performed +if a variable or temporary object with static or thread storage duration +is constant-initialized\iref{expr.const}. +\indextext{initialization!zero-initialization}% +If constant initialization is not performed, a variable with static +storage duration\iref{basic.stc.static} or thread storage +duration\iref{basic.stc.thread} is zero-initialized\iref{dcl.init}. +Together, zero-initialization and constant initialization are called +\defnadj{static}{initialization}; +all other initialization is \defnadj{dynamic}{initialization}. +All static initialization strongly happens before\iref{intro.races} +any dynamic initialization. \begin{note} -The \grammarterm{constraint-expression} cannot use -the \grammarterm{concept-name}. +The dynamic initialization of non-block variables is described +in~\ref{basic.start.dynamic}; that of static block variables is described +in~\ref{stmt.dcl}. \end{note} \pnum -The locus of a \grammarterm{namespace-definition} -with an \grammarterm{identifier} -is immediately after the \grammarterm{identifier}. -\begin{note} -An identifier is invented -for an \grammarterm{unnamed-namespace-definition}\iref{namespace.unnamed}. -\end{note} +An implementation is permitted to perform the initialization of a +variable with static or thread storage duration as a static +initialization even if such initialization is not required to be done +statically, provided that +\begin{itemize} +\item +the dynamic version of the initialization does not change the +value of any other object of static or thread storage duration +prior to its initialization, and -\pnum +\item +the static version of the initialization produces the same value +in the initialized variable as would be produced by the dynamic +initialization if all variables not required to be initialized statically +were initialized dynamically. +\end{itemize} \begin{note} -Friend declarations can introduce functions or classes -that belong to the nearest enclosing namespace or block scope, -but they do not bind names anywhere\iref{class.friend}. -Function declarations at block scope and -variable declarations with the \keyword{extern} specifier at block scope -declare entities -that belong to the nearest enclosing namespace, -but they do not bind names in it. +As a consequence, if the initialization of an object \tcode{obj1} refers to an +object \tcode{obj2} potentially requiring dynamic initialization and defined +later in the same translation unit, it is unspecified whether the value of \tcode{obj2} used +will be the value of the fully initialized \tcode{obj2} (because \tcode{obj2} was statically +initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example, +\begin{codeblock} +inline double fd() { return 1.0; } +extern double d1; +double d2 = d1; // unspecified: + // either statically initialized to \tcode{0.0} or + // dynamically initialized to \tcode{0.0} if \tcode{d1} is + // dynamically initialized, or \tcode{1.0} otherwise +double d1 = fd(); // either initialized statically or dynamically to \tcode{1.0} +\end{codeblock} \end{note} +\rSec3[basic.start.dynamic]{Dynamic initialization of non-block variables} + \pnum +\indextext{initialization!dynamic non-block}% +\indextext{start!program}% +\indextext{initialization!order of}% +Dynamic initialization of a non-block variable with static storage duration is +unordered if the variable is an implicitly or explicitly instantiated +specialization, is partially-ordered if the variable +is an inline variable that is not an implicitly or explicitly instantiated +specialization, and otherwise is ordered. \begin{note} -For point of instantiation of a template, see~\ref{temp.point}. +A non-inline explicit specialization of a templated variable +has ordered initialization. \end{note} -\indextext{locus|)} - -\rSec2[basic.scope.block]{Block scope} - -\indextext{local scope|see{scope, block}}% \pnum -Each +A declaration \tcode{D} is +\defn{appearance-ordered} before a declaration \tcode{E} if \begin{itemize} -\item -selection or iteration statement\iref{stmt.select,stmt.iter}, -\item -substatement of such a statement, -\item -\indextext{scope!\idxgram{handler}}% -\grammarterm{handler}\iref{except.pre}, or -\item -compound statement\iref{stmt.block} -that is not the \grammarterm{compound-statement} of a \grammarterm{handler} +\item \tcode{D} appears in the same translation unit as \tcode{E}, or +\item the translation unit containing \tcode{E} +has an interface dependency on the translation unit containing \tcode{D}, \end{itemize} -introduces a \defnadj{block}{scope} -that includes that statement or \grammarterm{handler}. -\begin{note} -A substatement that is also a block has only one scope. -\end{note} -A variable that belongs to a block scope is a \defn{block variable}. -\begin{example} -\begin{codeblock} -int i = 42; -int a[10]; - -for (int i = 0; i < 10; i++) - a[i] = i; - -int j = i; // \tcode{j = 42} -\end{codeblock} -\end{example} +in either case prior to \tcode{E}. \pnum -If a declaration -that is not a name-independent declaration and -that binds a name in the block scope $S$ of a +Dynamic initialization of non-block variables \tcode{V} and \tcode{W} +with static storage duration are ordered as follows: \begin{itemize} \item -\grammarterm{compound-statement} of a \grammarterm{lambda-expression}, -\grammarterm{function-body}, or \grammarterm{function-try-block}, +If \tcode{V} and \tcode{W} have ordered initialization and +the definition of \tcode{V} +is appearance-ordered before the definition of \tcode{W}, or +if \tcode{V} has partially-ordered initialization, +\tcode{W} does not have unordered initialization, and +for every definition \tcode{E} of \tcode{W} +there exists a definition \tcode{D} of \tcode{V} +such that \tcode{D} is appearance-ordered before \tcode{E}, then +\begin{itemize} \item -substatement of a selection or iteration statement -that is not itself a selection or iteration statement, or +if the program does not start a thread\iref{intro.multithread} +other than the main thread\iref{basic.start.main} +or \tcode{V} and \tcode{W} have ordered initialization and +they are defined in the same translation unit, +the initialization of \tcode{V} +is sequenced before +the initialization of \tcode{W}; \item -\grammarterm{handler} of a \grammarterm{function-try-block} +otherwise, +the initialization of \tcode{V} +strongly happens before +the initialization of \tcode{W}. \end{itemize} -potentially conflicts with a declaration -whose target scope is the parent scope of $S$, -the program is ill-formed. -\begin{example} -\begin{codeblock} -if (int x = f()) { - int x; // error: redeclaration of \tcode{x} -} -else { - int x; // error: redeclaration of \tcode{x} -} -\end{codeblock} -\end{example} -\rSec2[basic.scope.param]{Function parameter scope} +\item +Otherwise, if the program starts a thread +other than the main thread +before either \tcode{V} or \tcode{W} is initialized, +it is unspecified in which threads +the initializations of \tcode{V} and \tcode{W} occur; +the initializations are unsequenced if they occur in the same thread. -\indextext{scope!function prototype|see{scope, function parameter}}% -\indextext{parameter!scope of}% +\item +Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced. +\end{itemize} +\begin{note} +This definition permits initialization of a sequence of +ordered variables concurrently with another sequence. +\end{note} \pnum -A \grammarterm{parameter-declaration-clause} $P$ introduces -a \defnadj{function parameter}{scope} that includes $P$. -\begin{note} -A function parameter cannot be used for its value -within the \grammarterm{parameter-declaration-clause}\iref{dcl.fct.default}. -\end{note} -\begin{itemize} -\item -If $P$ is associated with a \grammarterm{declarator} and -is preceded by a (possibly-parenthesized) \grammarterm{noptr-declarator} of -the form -\grammarterm{declarator-id} \opt{\grammarterm{attribute-specifier-seq}}, -its scope extends to the end of the nearest enclosing -\grammarterm{init-declarator}, -\grammarterm{member-declarator}, -\grammarterm{declarator} of a \grammarterm{parameter-declaration} or -a \grammarterm{nodeclspec-function-declaration}, or -\grammarterm{function-definition}, -but does not include the locus of the associated \grammarterm{declarator}. -\begin{note} -In this case, $P$ declares the parameters of a function -(or a function or template parameter declared with function type). -A member function's parameter scope is nested within its class's scope. -\end{note} -\item -If $P$ is associated with a \grammarterm{lambda-declarator}, -its scope extends to the end of the \grammarterm{compound-statement} -in the \grammarterm{lambda-expression}. -\item -If $P$ is associated with a \grammarterm{requirement-parameter-list}, -its scope extends to the end of the \grammarterm{requirement-body} of the \grammarterm{requires-expression}. -\item -If $P$ is associated with a \grammarterm{deduction-guide}, -its scope extends to the end of the \grammarterm{deduction-guide}. -\end{itemize} - -\rSec2[basic.scope.lambda]{Lambda scope} - -A \grammarterm{lambda-expression} \tcode{E} introduces a \defnadj{lambda}{scope} -that starts immediately after the \grammarterm{lambda-introducer} of \tcode{E} -and extends to the end of the \grammarterm{compound-statement} of \tcode{E}. - -\rSec2[basic.scope.namespace]{Namespace scope} +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% +A \defnx{non-initialization odr-use}{odr-use!non-initialization} +is an odr-use\iref{term.odr.use} not caused directly or indirectly by +the initialization of a non-block static or thread storage duration variable. \pnum -Any \grammarterm{namespace-definition} for a namespace $N$ introduces -a \defnadj{namespace}{scope} -that includes the \grammarterm{namespace-body} -for every \grammarterm{namespace-definition} for $N$. -For each non-friend redeclaration or specialization -whose target scope is or is contained by the scope, -the portion after the -\grammarterm{declarator-id}, -\grammarterm{class-head-name}, or -\grammarterm{enum-head-name} -is also included in the scope. -The global scope is -the namespace scope of the global namespace\iref{basic.namespace}. +\indextext{evaluation!unspecified order of}% +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether the dynamic initialization of a +non-block non-inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of any non-inline function or non-inline variable +defined in the same translation unit as the variable to be initialized. +\begin{footnote} +A non-block variable with static storage duration +having initialization +with side effects is initialized in this case, +even if it is not itself odr-used\iref{term.odr.use,basic.stc.static}. +\end{footnote} +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. + +\recommended +An implementation should choose such points in a way +that allows the programmer to avoid deadlocks. \begin{example} \begin{codeblock} -namespace Q { - namespace V { void f(); } - void V::f() { // in the scope of \tcode{V} - void h(); // declares \tcode{Q::V::h} - } +// - File 1 - +#include "a.h" +#include "b.h" +B b; +A::A() { + b.Use(); } -\end{codeblock} -\end{example} -\rSec2[basic.scope.class]{Class scope} +// - File 2 - +#include "a.h" +A a; -\pnum -Any declaration of a class or class template $C$ introduces -a \defnadj{class}{scope} -that includes the \grammarterm{member-specification} of -the \grammarterm{class-specifier} for $C$ (if any). -For each non-friend redeclaration or specialization -whose target scope is or is contained by the scope, -the portion after the -\grammarterm{declarator-id}, -\grammarterm{class-head-name}, or -\grammarterm{enum-head-name} is also included in the scope. -\begin{note} -Lookup from a program point -before the \grammarterm{class-specifier} of a class -will find no bindings in the class scope. -\begin{example} -\begin{codeblock} -template -struct B { - D::type x; // \#1 -}; +// - File 3 - +#include "a.h" +#include "b.h" +extern A a; +extern B b; -struct A { using type = int; }; -struct C : A, B {}; // error at \#1: \tcode{C::type} not found +int main() { + a.Use(); + b.Use(); +} \end{codeblock} -\end{example} -\end{note} -\rSec2[basic.scope.enum]{Enumeration scope}% +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether either \tcode{a} or \tcode{b} is +initialized before \tcode{main} is entered or whether the +initializations are delayed until \tcode{a} is first odr-used in +\tcode{main}. In particular, if \tcode{a} is initialized before +\tcode{main} is entered, it is not guaranteed that \tcode{b} will be +initialized before it is odr-used by the initialization of \tcode{a}, that +is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized +at some point after the first statement of \tcode{main}, \tcode{b} will +be initialized prior to its use in \tcode{A::A}. +\end{example} \pnum -Any declaration of an enumeration $E$ introduces -an \defnadj{enumeration}{scope} -that includes the \grammarterm{enumerator-list} of -the \grammarterm{enum-specifier} for $E$ (if any). +It is \impldef{dynamic initialization of static inline variables before \tcode{main}} +whether the dynamic initialization of a +non-block inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of that variable. +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. -\rSec2[basic.scope.temp]{Template parameter scope}% +\pnum +It is \impldef{dynamic initialization of thread-local variables before entry} +whether the dynamic initialization of a +non-block non-inline variable with thread storage duration +is sequenced before the first statement of the initial function of a thread or is deferred. +If it is deferred, +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 +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. \pnum -Each template \grammarterm{template-parameter} introduces -a \defnadj{template parameter}{scope} -that includes the \grammarterm{template-head} of -the \grammarterm{template-parameter}. +If the initialization of +a non-block variable with static or thread storage duration +exits via an exception, +the function \tcode{std::terminate} is called\iref{except.terminate}.% +\indextext{program!startup|)} + +\rSec3[basic.start.term]{Termination} \pnum -Each \grammarterm{template-declaration} $D$ introduces -a template parameter scope -that extends from the beginning of its \grammarterm{template-parameter-list} -to the end of the \grammarterm{template-declaration}. -Any declaration outside the \grammarterm{template-parameter-list} -that would inhabit that scope instead inhabits the same scope as $D$. -The parent scope of any scope $S$ that is not a template parameter scope -is the smallest scope that contains $S$ and is not a template parameter scope. +\indextext{program!termination|(}% +\indextext{object!destructor static}% +\indextext{\idxcode{main} function!return from}% +Constructed 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 +\indextext{\idxcode{exit}}% +\indexlibraryglobal{exit}% +\tcode{std::exit}\iref{support.start.term}. +The call to \tcode{std::exit} is sequenced before +the destructions and the registered functions. \begin{note} -Therefore, only template parameters belong to a template parameter scope, and -only template parameter scopes have -a template parameter scope as a parent scope. +Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. \end{note} -\indextext{scope|)} +\pnum +Constructed 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 +any object with static storage duration. -\rSec1[basic.lookup]{Name lookup}% +\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. +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. +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}. -\indextext{lookup!name|(} +\pnum +If a function contains a block variable of static or thread storage duration that has been +destroyed and the function is called during the destruction of an object with static or +thread storage duration, the program has undefined behavior if the flow of control +passes through the definition of the previously destroyed block variable. +\begin{note} +Likewise, the behavior is undefined +if the block variable is used indirectly (e.g., through a pointer) +after its destruction. +\end{note} -\rSec2[basic.lookup.general]{General}% -\indextext{scope!name lookup and|see{lookup, name}}% +\pnum +\indextext{\idxcode{atexit}}% +\indexlibraryglobal{atexit}% +If the completion of the initialization of an 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 +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 +the call to the function passed to the first \tcode{std::atexit} call. \pnum -The name lookup rules apply uniformly to all names (including -\grammarterm{typedef-name}{s}\iref{dcl.typedef}, -\grammarterm{namespace-name}{s}\iref{basic.namespace}, and -\grammarterm{class-name}{s}\iref{class.name}) wherever the grammar allows -such names in the context discussed by a particular rule. Name lookup -associates the use of a name with a set of declarations\iref{basic.def} of -that name. -Unless otherwise specified, -the program is ill-formed if no declarations are found. -If the declarations found by name lookup -all denote functions or function templates, -the declarations are said to form an \defn{overload set}. -Otherwise, -if the declarations found by name lookup do not all denote the same entity, -\indextext{lookup!ambiguous}% -they are \defn{ambiguous} and the program is ill-formed. -Overload resolution\iref{over.match,over.over} -takes place after name lookup has succeeded. The access rules\iref{class.access} -are considered only once name lookup and -function overload resolution (if applicable) have succeeded. Only after -name lookup, function overload resolution (if applicable) and access -checking have succeeded -are the semantic properties introduced by the declarations -used in further processing. +If there is a use of a standard library object or function not permitted within signal +handlers\iref{support.runtime} that does not happen before\iref{intro.multithread} +completion of destruction of objects with static storage duration and execution of +\tcode{std::atexit} registered functions\iref{support.start.term}, the program has +undefined behavior. +\begin{note} +If there is a use of an object with static storage +duration that does not happen before the object's destruction, the program has undefined +behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from +\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These +requirements permit thread managers as static-storage-duration objects. +\end{note} \pnum -A program point $P$ is said to follow -any declaration in the same translation unit -whose locus\iref{basic.scope.pdecl} is before $P$. +\indextext{\idxcode{abort}}% +\indexlibraryglobal{abort}% +\indextext{termination!program}% +Calling the function \tcode{std::abort()} declared in +\libheaderref{cstdlib} terminates the program without executing any destructors +and without calling +the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% +\indextext{program!termination|)} + +\rSec3[except.terminate]{The \tcode{std::terminate} function} + +\pnum +\indextext{\idxcode{terminate}}% +In some situations the \Cpp{} runtime encounters an error that cannot be recovered, +such as when an exception is not handled, or a thread is destroyed while still running. +In such cases, +the function \tcode{std::terminate} is invoked\iref{exception.terminate}. \begin{note} -The declaration might appear in a scope that does not contain $P$. -\end{note} -\indextext{precede|see{declaration, precede}}% -A declaration $X$ \defnx{precedes}{declaration!precede} -a program point $P$ in a translation unit $L$ -if $P$ follows $X$, $X$ inhabits a class scope and is reachable from $P$, or -else $X$ appears in a translation unit $D$ and +These situations are: +\indextext{\idxcode{terminate}!called}% \begin{itemize} -\item -$P$ follows -a \grammarterm{module-import-declaration} or \grammarterm{module-declaration} -that imports $D$ (directly or indirectly), and -\item -$X$ appears after the \grammarterm{module-declaration} in $D$ (if any) and -before the \grammarterm{private-module-fragment} in $D$ (if any), and -\item -either $X$ is exported or else $D$ and $L$ are part of the same module and -$X$ does not inhabit a namespace with internal linkage or -declare a name with internal linkage. -\begin{note} -Names declared by a \grammarterm{using-declaration} have no linkage. -\end{note} +\item% +when initialization of a non-block +variable with static or thread storage duration\iref{basic.start.dynamic} +exits via an exception, or + +\item% +when destruction of an object with static or thread storage duration exits +via an exception\iref{basic.start.term}, or + +\item% +when a +\grammarterm{throw-expression}\iref{expr.throw} +with no operand attempts to rethrow an exception and no exception is being +handled\iref{except.throw}, or + +\item% +when the exception handling mechanism, after completing +the initialization of the exception object +but before +activation of a handler for the exception\iref{except.throw}, +calls a function that exits +via an exception, or + +\item% +when the destruction of an object during stack unwinding\iref{except.ctor} +terminates by throwing an exception, or + +\item when the search for a handler\iref{except.handle} encounters the +outermost block of a function +with a non-throwing exception specification, or + +\item% +when the exception handling mechanism cannot find a handler for a thrown exception\iref{except.handle}, or + +\item% +when execution of a function registered with +\tcode{std::atexit} or \tcode{std::at_quick_exit} +exits via an exception\iref{support.start.term}, or + +\item% +when the function \tcode{std::nested_exception::rethrow_nested} is called for an object +that has captured no exception\iref{except.nested}, or + +\item% +for a parallel algorithm whose \tcode{ExecutionPolicy} specifies such +behavior\iref{execpol.seq,execpol.par,execpol.parunseq}, +when execution of an element access function\iref{algorithms.parallel.defns} +of the parallel algorithm exits via an exception\iref{algorithms.parallel.exceptions}, or + +\item% +when a callback invocation exits via an exception +when requesting stop on +a \tcode{std::stop_source} or +a \tcode{std::in\-place_stop_source}\iref{stopsource.mem,stopsource.inplace.mem}, +or in the constructor of +\tcode{std::stop_callback} or +\tcode{std::inplace_stop_callback}\iref{stopcallback.cons,stopcallback.inplace.cons} +when a callback invocation exits via an exception, or + +\item% +when execution of the initial function of a thread exits via +an exception\iref{thread.thread.constr}, or + +\item% +when the destructor or the move assignment operator is invoked on an object +of type \tcode{std::thread} that refers to +a joinable thread\iref{thread.thread.destr,thread.thread.assign}, or + +\item% +when a call to a \tcode{wait()}, \tcode{wait_until()}, or \tcode{wait_for()} +function on a condition variable\iref{thread.condition.condvar,thread.condition.condvarany} +fails to meet a postcondition, or + +\item% +when a \tcode{run_loop} object is destroyed +that is still in the \tcode{running} state\iref{exec.run.loop}, or + +\item% +when \tcode{unhandled_stopped} is called on +a \tcode{with_awaitable_senders} object\iref{exec.with.awaitable.senders} +whose continuation is not a handle to a coroutine +whose promise type has an \tcode{unhandled_stopped} member function. + \end{itemize} -\begin{note} -A \grammarterm{module-import-declaration} imports both -the named translation unit(s) and -any modules named by exported -\grammarterm{module-import-declaration}{s} within them, -recursively. -\begin{example} -\begin{codeblocktu}{Translation unit \#1} -export module Q; -export int sq(int i) { return i*i; } -\end{codeblocktu} +\end{note} -\begin{codeblocktu}{Translation unit \#2} -export module R; -export import Q; -\end{codeblocktu} +\pnum +In the situation where no matching handler is found, it is +\impldef{stack unwinding before invocation of \tcode{std::terminate}} +whether or not the stack is unwound +before \tcode{std::terminate} is invoked. +In the situation where the search for a handler\iref{except.handle} encounters the +outermost block of a function +with a non-throwing exception specification, it is +\impldef{whether stack is unwound before invoking the function \tcode{std::terminate} +when a \tcode{noexcept} specification is violated} +whether the stack is unwound, unwound partially, or not unwound at all +before the function \tcode{std::terminate} is invoked. +In all other situations, the stack shall not be unwound before +the function \tcode{std::terminate} +is invoked. +An implementation is not permitted to finish stack unwinding +prematurely based on a determination that the unwind process +will eventually cause an invocation of the function +\tcode{std::terminate}. +\indextext{program execution|)} -\begin{codeblocktu}{Translation unit \#3} -import R; -int main() { return sq(9); } // OK, \tcode{sq} from module \tcode{Q} -\end{codeblocktu} -\end{example} -\end{note} +\rSec1[basic.memobj]{Memory and objects} + +\rSec2[intro.memory]{Memory model} \pnum -\indextext{scope!search!single}% -A \defnadj{single}{search} in a scope $S$ -for a name $N$ from a program point $P$ -finds all declarations that precede $P$ -to which any name that is the same as $N$\iref{basic.pre} is bound in $S$. -If any such declaration is a \grammarterm{using-declarator} -whose terminal name\iref{expr.prim.id.unqual} -is not dependent\iref{temp.dep.type}, -it is replaced by the declarations named by -the \grammarterm{using-declarator}\iref{namespace.udecl}. +\indextext{memory model|(}% +The fundamental storage unit in the \Cpp{} memory model is the +\defn{byte}. +A byte is at least large enough to contain +the ordinary literal encoding of any element of the basic +\indextext{character set!basic literal}% +literal character set\iref{lex.charset} +and the eight-bit code units of the Unicode +\indextext{UTF-8}% +UTF-8 encoding form +and is composed of a contiguous sequence of +bits, +\begin{footnote} +The number of bits in a byte is reported by the macro +\tcode{CHAR_BIT} in the header \libheaderref{climits}. +\end{footnote} +the number of which is \impldef{bits in a byte}. The least +significant bit is called the \defn{low-order bit}; the most +significant bit is called the \defn{high-order bit}. The memory +available to a \Cpp{} program consists of one or more sequences of +contiguous bytes. Every byte has a unique address. \pnum -In certain contexts, only certain kinds of declarations are included. -After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found. \begin{note} -A type (but not a \grammarterm{typedef-name} or template) -is therefore hidden by any other entity in its scope. +The representation of types is described +in~\ref{basic.types.general}. \end{note} -\indextext{type-only!lookup|see{lookup, type-only}}% -However, if a lookup is \defnx{type-only}{lookup!type-only}, -only declarations of -types and templates whose specializations are types are considered; -furthermore, if declarations -of a \grammarterm{typedef-name} and of the type to which it refers are found, -the declaration of the \grammarterm{typedef-name} is discarded -instead of the type declaration. - -\rSec2[class.member.lookup]{Member name lookup}% -\indextext{lookup!member name}% -\indextext{ambiguity!base class member}% -\indextext{ambiguity!member access} \pnum -\indextext{scope!search}% -A \defn{search} in a scope $X$ for a name $M$ from a program point $P$ -is a single search in $X$ for $M$ from $P$ -unless $X$ is the scope of a class or class template $T$, in which case the -following steps define the result of the search. +A \defn{memory location} is either an object of scalar type that is not a bit-field +or a maximal sequence of adjacent bit-fields all having nonzero width. \begin{note} -The result differs only -if $M$ is a \grammarterm{conversion-function-id} or -if the single search would find nothing. +Various +features of the language, such as references and virtual functions, might +involve additional memory locations that are not accessible to programs but are +managed by the implementation. \end{note} +Two or more threads of +execution\iref{intro.multithread} can access separate memory +locations without interfering with each other. \pnum -The \defn{lookup set} for a name $N$ in a class or class template $C$, called $S(N,C)$, -consists of two component sets: -the \term{declaration set}, a set of members named $N$; and -the \term{subobject set}, -a set of subobjects where declarations of these members were found -(possibly via \grammarterm{using-declaration}{s}). -In the declaration set, type declarations (including injected-class-names) -are replaced by the types they designate. $S(N,C)$ is calculated as follows: - -\pnum -The declaration set is the result of -a single search in the scope of $C$ for $N$ -from immediately after the \grammarterm{class-specifier} of $C$ -if $P$ is in a complete-class context of $C$ or -from $P$ otherwise. -If the resulting declaration set is not empty, the subobject set -contains $C$ itself, and calculation is complete. - -\pnum -Otherwise (i.e., $C$ does not contain a declaration of $N$ -or the resulting declaration set is empty), $S(N,C)$ is initially empty. -Calculate the lookup set for $N$ -in each direct non-dependent\iref{temp.dep.type} base class subobject $B_i$, and -merge each such lookup set $S(N,B_i)$ in turn into $S(N,C)$. \begin{note} -If $C$ is incomplete, -only base classes whose \grammarterm{base-specifier} appears before $P$ -are considered. -If $C$ is an instantiated class, its base classes are not dependent. +Thus a bit-field and an adjacent non-bit-field are in separate memory +locations, and therefore can be concurrently updated by two threads of execution +without interference. The same applies to two bit-fields, if one is declared +inside a nested struct declaration and the other is not, or if the two are +separated by a zero-length bit-field declaration, or if they are separated by a +non-bit-field declaration. It is not safe to concurrently update two bit-fields +in the same struct if all fields between them are also bit-fields of nonzero +width. \end{note} \pnum -The following steps define the result of merging lookup set $S(N,B_i)$ -into the intermediate $S(N,C)$: - -\begin{itemize} -\item If each of the subobject members of $S(N,B_i)$ is a base class -subobject of at least one of the subobject members of $S(N,C)$, or if -$S(N,B_i)$ is empty, $S(N,C)$ is unchanged and the merge is complete. -Conversely, if each of the subobject members of $S(N,C)$ is a base class -subobject of at least one of the subobject members of $S(N,B_i)$, or if -$S(N,C)$ is empty, the new $S(N,C)$ is a copy of $S(N,B_i)$. - -\item Otherwise, if the declaration sets of $S(N,B_i)$ and $S(N,C)$ -differ, the merge is ambiguous: the new $S(N,C)$ is a lookup set with an -invalid declaration set and the union of the subobject sets. In -subsequent merges, an invalid declaration set is considered different -from any other. - -\item Otherwise, the new $S(N,C)$ is a lookup set with the shared set of -declarations and the union of the subobject sets. -\end{itemize} - -\pnum -The result of the search is the declaration set of $S(M,T)$. -If it is an invalid set, the program is ill-formed. -If it differs from the result of a search in $T$ for $M$ -in a complete-class context\iref{class.mem} of $T$, -the program is ill-formed, no diagnostic required. \begin{example} +A class declared as \begin{codeblock} -struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} -struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} -struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} -struct D: public virtual C { }; // S(x,D) = S(x,C) -struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} -struct F: public D, public E { }; // S(x,F) = S(x,E) -int main() { - F f; - f.x = 0; // OK, lookup finds \tcode{E::x} -} +struct { + char a; + int b:5, + c:11, + :0, + d:8; + struct {int ee:8;} e; +}; \end{codeblock} +contains four separate memory locations: The member \tcode{a} and bit-fields +\tcode{d} and \tcode{e.ee} are each separate memory locations, and can be +modified concurrently without interfering with each other. The bit-fields +\tcode{b} and \tcode{c} together constitute the fourth memory location. The +bit-fields \tcode{b} and \tcode{c} cannot be concurrently modified, but +\tcode{b} and \tcode{a}, for example, can be. +\end{example} +\indextext{memory model|)} -$S(\tcode{x},\tcode{F})$ is unambiguous because the \tcode{A} and \tcode{B} base -class subobjects of \tcode{D} are also base class subobjects of \tcode{E}, so -$S(\tcode{x},\tcode{D})$ is discarded in the first merge step. -\end{example} +\rSec2[intro.object]{Object model} \pnum -If $M$ is a non-dependent \grammarterm{conversion-function-id}, -conversion function templates that are members of $T$ are considered. -For each such template $F$, the lookup set $S(t,T)$ is constructed, -considering a function template declaration to have the name $t$ -only if it corresponds to a declaration of $F$\iref{basic.scope.scope}. -The members of the declaration set of each such lookup set, -which shall not be an invalid set, are included in the result. +\indextext{object model|(}% +The constructs in a \Cpp{} program create, destroy, refer to, access, and +manipulate objects. +An \defn{object} is created +by a definition\iref{basic.def}, +by a \grammarterm{new-expression}\iref{expr.new}, +by an operation that implicitly creates objects (see below), +when implicitly changing the active member of a union\iref{class.union}, +or +when a temporary object is created\iref{conv.rval,class.temporary}. +An object occupies a region of storage +in its period of construction\iref{class.cdtor}, +throughout its lifetime\iref{basic.life}, +and +in its period of destruction\iref{class.cdtor}. \begin{note} -Overload resolution will discard those -that cannot convert to the type specified by $M$\iref{temp.over}. +A function is not an object, regardless of whether or not it +occupies storage in the way that objects do. \end{note} - -\pnum +The properties of an +object are determined when the object is created. An object can have a +name\iref{basic.link}. An object has a storage +duration\iref{basic.stc} which influences its +lifetime\iref{basic.life}. An object has a +type\iref{basic.types}. \begin{note} -A static member, a nested type or an enumerator defined in a base class -\tcode{T} can unambiguously be found even if an object has more than one -base class subobject of type \tcode{T}. Two base class subobjects share -the non-static member subobjects of their common virtual base classes. +Some objects are +polymorphic\iref{class.virtual}; the implementation +generates information associated with each such object that makes it +possible to determine that object's type during program execution. \end{note} -\begin{example} -\begin{codeblock} -struct V { - int v; -}; -struct A { - int a; - static int s; - enum { e }; -}; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; -void f(D* pd) { - pd->v++; // OK, only one \tcode{v} (virtual) - pd->s++; // OK, only one \tcode{s} (static) - int i = pd->e; // OK, only one \tcode{e} (enumerator) - pd->a++; // error: ambiguous: two \tcode{a}{s} in \tcode{D} -} -\end{codeblock} -\end{example} +\pnum +\indextext{subobject}% +Objects can contain other objects, called \defnx{subobjects}{subobject}. +A subobject can be +a \defn{member subobject}\iref{class.mem}, a \defn{base class subobject}\iref{class.derived}, +or an array element. +\indextext{object!complete}% +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} +(which may or may not be within its lifetime), +the created object +is a subobject of \placeholder{e}'s containing object if +\begin{itemize} +\item +the lifetime of \placeholder{e}'s containing object has begun and not ended, and +\item +the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and +\item +the new object is of the same type as \placeholder{e} (ignoring cv-qualification). +\end{itemize} \pnum +\indextext{object!providing storage for}% +If a complete object is created\iref{expr.new} +in storage associated with another object \placeholder{e} +of type ``array of $N$ \tcode{\keyword{unsigned} \keyword{char}}'' or +of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, +that array \defn{provides storage} +for the created object if +\begin{itemize} +\item +the lifetime of \placeholder{e} has begun and not ended, and +\item +the storage for the new object fits entirely within \placeholder{e}, and +\item +there is no array object that satisfies these constraints nested within \placeholder{e}. +\end{itemize} \begin{note} -\indextext{dominance!virtual base class}% -When virtual base classes are used, a hidden declaration can be reached -along a path through the subobject lattice that does not pass through -the hiding declaration. This is not an ambiguity. The identical use with -non-virtual base classes is an ambiguity; in that case there is no -unique instance of the name that hides all the others. +If that portion of the array +previously provided storage for another object, +the lifetime of that object ends +because its storage was reused\iref{basic.life}. \end{note} \begin{example} \begin{codeblock} -struct V { int f(); int x; }; -struct W { int g(); int y; }; -struct B : virtual V, W { - int f(); int x; - int g(); int y; -}; -struct C : virtual V, W { }; - -struct D : B, C { void glorp(); }; -\end{codeblock} - -\begin{importgraphic} -{Name lookup} -{class.lookup} -{figname.pdf} -\end{importgraphic} +// assumes that \tcode{sizeof(int)} is equal to 4 -As illustrated in \fref{class.lookup}, -the names declared in \tcode{V} and the left-hand instance of \tcode{W} -are hidden by those in \tcode{B}, but the names declared in the -right-hand instance of \tcode{W} are not hidden at all. -\begin{codeblock} -void D::glorp() { - x++; // OK, \tcode{B::x} hides \tcode{V::x} - f(); // OK, \tcode{B::f()} hides \tcode{V::f()} - y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} - g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} +template +struct AlignedUnion { + alignas(T...) unsigned char data[max(sizeof(T)...)]; +}; +int f() { + AlignedUnion au; + int *p = new (au.data) int; // OK, \tcode{au.data} provides storage + char *c = new (au.data) char(); // OK, ends lifetime of \tcode{*p} + char *d = new (au.data + 1) char(); + return *c + *d; // OK } -\end{codeblock} -\end{example} -\indextext{ambiguity!class conversion}% - -\pnum -An explicit or implicit conversion from a pointer to or -an expression designating an object -of a -derived class to a pointer or reference to one of its base classes shall -unambiguously refer to a unique object representing the base class. -\begin{example} -\begin{codeblock} -struct V { }; -struct A { }; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; -void g() { - D d; - B* pb = &d; - A* pa = &d; // error: ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? - V* pv = &d; // OK, only one \tcode{V} subobject -} +struct A { unsigned char a[32]; }; +struct B { unsigned char b[16]; }; +alignas(int) A a; +B *b = new (a.a + 8) B; // \tcode{a.a} provides storage for \tcode{*b} +int *p = new (b->b + 4) int; // \tcode{b->b} provides storage for \tcode{*p} + // \tcode{a.a} does not provide storage for \tcode{*p} (directly), + // but \tcode{*p} is nested within \tcode{a} (see below) \end{codeblock} \end{example} \pnum -\begin{note} -Even if the result of name lookup is unambiguous, use of a name found in -multiple subobjects might still be -ambiguous\iref{conv.mem,expr.ref,class.access.base}. -\end{note} -\begin{example} -\begin{codeblock} -struct B1 { - void f(); - static void f(int); - int i; -}; -struct B2 { - void f(double); -}; -struct I1: B1 { }; -struct I2: B1 { }; - -struct D: I1, I2, B2 { - using B1::f; - using B2::f; - void g() { - f(); // Ambiguous conversion of \keyword{this} - f(0); // Unambiguous (static) - f(0.0); // Unambiguous (only one \tcode{B2}) - int B1::* mpB1 = &D::i; // Unambiguous - int D::* mpD = &D::i; // Ambiguous conversion - } -}; -\end{codeblock} -\end{example} +\indextext{object!nested within}% +An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if +\begin{itemize} +\item +\placeholder{a} is a subobject of \placeholder{b}, or +\item +\placeholder{b} provides storage for \placeholder{a}, or +\item +there exists an object \placeholder{c} +where \placeholder{a} is nested within \placeholder{c}, +and \placeholder{c} is nested within \placeholder{b}. +\end{itemize} -\rSec2[basic.lookup.unqual]{Unqualified name lookup} +\pnum +For every object \tcode{x}, there is some object called the +\defn{complete object of} \tcode{x}, determined as follows: +\begin{itemize} +\item +If \tcode{x} is a complete object, then the complete object +of \tcode{x} is itself. -\indextext{name!unqualified}% +\item +Otherwise, the complete object of \tcode{x} is the complete object +of the (unique) object that contains \tcode{x}. +\end{itemize} \pnum -A \grammarterm{using-directive} is -\term{active} in a scope $S$ at a program point $P$ -if it precedes $P$ and inhabits either $S$ or -the scope of a namespace nominated by a \grammarterm{using-directive} -that is active in $S$ at $P$. +If a complete object, a member subobject, or an array element is of +class type, its type is considered the \defn{most derived +class}, to distinguish it from the class type of any base class subobject; +an object of a most derived class type or of a non-class type is called a +\defn{most derived object}. \pnum -An \term{unqualified search} in a scope $S$ from a program point $P$ -includes the results of searches from $P$ in +A \defn{potentially-overlapping subobject} is either: \begin{itemize} -\item -$S$, and -\item -for any scope $U$ that contains $P$ and is or is contained by $S$, -each namespace contained by $S$ that is nominated by -a \grammarterm{using-directive} that is active in $U$ at $P$. -\end{itemize} -If no declarations are found, -the results of the unqualified search are -the results of an unqualified search in the parent scope of $S$, if any, -from $P$. -\begin{note} -When a class scope is searched, -the scopes of its base classes are also searched\iref{class.member.lookup}. -If it inherits from a single base, -it is as if the scope of the base immediately contains -the scope of the derived class. -Template parameter scopes -that are associated with one scope in the chain of parents -are also considered\iref{temp.local}. -\end{note} +\item a base class subobject, or +\item a non-static data member +declared with the \tcode{no_unique_address} attribute\iref{dcl.attr.nouniqueaddr}. +\end{itemize} \pnum -\defnx{Unqualified name lookup}{lookup!unqualified name} -from a program point performs an unqualified search in its immediate scope. +\indextext{object!zero size}% +\indextext{object!nonzero size}% +An object has nonzero size if it +\begin{itemize} +\item is not a potentially-overlapping subobject, or +\item is not of class type, or +\item is of a class type with virtual member functions or virtual base classes, or +\item has subobjects of nonzero size or unnamed bit-fields of nonzero length. +\end{itemize} +Otherwise, if the object is a base class subobject +of a standard-layout class type +with no non-static data members, +it has zero size. +Otherwise, the circumstances under which the object has zero size +are \impldef{which non-standard-layout objects +containing no data are considered empty}. +\indextext{most derived object!bit-field}% +Unless it is a bit-field\iref{class.bit}, +an object with nonzero size +shall occupy one or more bytes of storage, +including every byte that is occupied in full or in part +by any of its subobjects. +An object of trivially copyable or +standard-layout type\iref{basic.types.general} shall occupy contiguous bytes of +storage. \pnum -An \defnadj{unqualified}{name} is a name -that does not immediately follow a \grammarterm{nested-name-specifier} or -the \tcode{.} or \tcode{->} in a class member access expression\iref{expr.ref}, -possibly after a \keyword{template} keyword or \tcode{\~}. -Unless otherwise specified, -such a name undergoes unqualified name lookup from the point where it appears. +An object is a \defnadj{potentially non-unique}{object} if it is +a string literal object\iref{lex.string}, +the backing array of an initializer list\iref{dcl.init.ref}, or +a subobject thereof. \pnum -An unqualified name that is a component name\iref{expr.prim.id.unqual} of -a \grammarterm{type-specifier} or \grammarterm{ptr-operator} of -a \grammarterm{conversion-type-id} is looked up in the same fashion -as the \grammarterm{conversion-function-id} in which it appears. -If that lookup finds nothing, it undergoes unqualified name lookup; -in each case, only names -that denote types or templates whose specializations are types are considered. +\indextext{most derived object!bit-field}% +\indextext{most derived object!zero size subobject}% +Unless an object is a bit-field or a subobject of zero size, the +address of that object is the address of the first byte it occupies. +Two objects +with overlapping lifetimes +that are not bit-fields +may have the same address if +\begin{itemize} +\item one is nested within the other, +\item at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, +or +\item they are both potentially non-unique objects; +\end{itemize} +otherwise, they have distinct addresses +and occupy disjoint bytes of storage. +\begin{footnote} +Under the ``as-if'' rule an +implementation is allowed to store two objects at the same machine address or +not store an object at all if the program cannot observe the +difference\iref{intro.execution}. +\end{footnote} \begin{example} \begin{codeblock} -struct T1 { struct U { int i; }; }; -struct T2 { }; -struct U1 {}; -struct U2 {}; - -struct B { - using T = T1; - using U = U1; - operator U1 T1::*(); - operator U1 T2::*(); - operator U2 T1::*(); - operator U2 T2::*(); -}; +static const char test1 = 'x'; +static const char test2 = 'x'; +const bool b = &test1 != &test2; // always \tcode{true} -template -int g() { - using U = U2; - X().operator U T::*(); // \#1, searches for \tcode{T} in the scope of \tcode{X} first - X().operator U decltype(T())::*(); // \#2 - return 0; -} -int x = g(); // \#1 calls \tcode{B::operator U1 T1::*} - // \#2 calls \tcode{B::operator U1 T2::*} +static const char (&r) [] = "x"; +static const char *s = "x"; +static std::initializer_list il = { 'x' }; +const bool b2 = r != il.begin(); // unspecified result +const bool b3 = r != s; // unspecified result +const bool b4 = il.begin() != &test1; // always \tcode{true} +const bool b5 = r != &test1; // always \tcode{true} \end{codeblock} \end{example} +The address of a non-bit-field subobject of zero size is +the address of an unspecified byte of storage +occupied by the complete object of that subobject. \pnum -In a friend declaration \grammarterm{declarator} -whose \grammarterm{declarator-id} is a \grammarterm{qualified-id} -whose lookup context\iref{basic.lookup.qual} is a class or namespace $S$, -lookup for an unqualified name -that appears after the \grammarterm{declarator-id} -performs a search in the scope associated with $S$. -If that lookup finds nothing, it undergoes unqualified name lookup. -\begin{example} -\begin{codeblock} -using I = int; -using D = double; -namespace A { - inline namespace N {using C = char; } - using F = float; - void f(I); - void f(D); - void f(C); - void f(F); -} -struct X0 {using F = float; }; -struct W { - using D = void; - struct X : X0 { - void g(I); - void g(::D); - void g(F); - }; -}; -namespace B { - typedef short I, F; - class Y { - friend void A::f(I); // error: no \tcode{void A::f(short)} - friend void A::f(D); // OK - friend void A::f(C); // error: \tcode{A::N::C} not found - friend void A::f(F); // OK - friend void W::X::g(I); // error: no \tcode{void X::g(short)} - friend void W::X::g(D); // OK - friend void W::X::g(F); // OK - }; -} -\end{codeblock} -\end{example} +Some operations are described as +\defnx{implicitly creating objects}{object!implicit creation} +within a specified region of storage. +For each operation that is specified as implicitly creating objects, +that operation implicitly creates and starts the lifetime of +zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type} +in its specified region of storage +if doing so would result in the program having defined behavior. +If no such set of objects would give the program defined behavior, +the behavior of the program is undefined. +If multiple such sets of objects would give the program defined behavior, +it is unspecified which such set of objects is created. +\begin{note} +Such operations do not start the lifetimes of subobjects of such objects +that are not themselves of implicit-lifetime types. +\end{note} -\rSec2[basic.lookup.argdep]{Argument-dependent name lookup}% -\indextext{lookup!argument-dependent} +\pnum +Further, after implicitly creating objects within a specified region of storage, +some operations are described as producing a pointer to a +\defnadj{suitable created}{object}. +These operations select one of the implicitly-created objects +whose address is the address of the start of the region of storage, +and produce a pointer value that points to that object, +if that value would result in the program having defined behavior. +If no such pointer value would give the program defined behavior, +the behavior of the program is undefined. +If multiple such pointer values would give the program defined behavior, +it is unspecified which such pointer value is produced. \pnum -When the \grammarterm{postfix-expression} in -a function call\iref{expr.call} is an \grammarterm{unqualified-id}, -and unqualified lookup\iref{basic.lookup.unqual} -for the name in the \grammarterm{unqualified-id} does not find any -\begin{itemize} -\item -declaration of a class member, or -\item -function declaration inhabiting a block scope, or -\item -declaration not of a function or function template -\end{itemize} -then lookup for the name also includes the result of -\defnadj{argument-dependent}{lookup} in a set of associated namespaces -that depends on the types of the arguments -(and for template template arguments, the namespace of the template argument), -as specified below. \begin{example} \begin{codeblock} -namespace N { - struct S { }; - void f(S); -} - -void g() { - N::S s; - f(s); // OK, calls \tcode{N::f} - (f)(s); // error: \tcode{N::f} not considered; parentheses prevent argument-dependent lookup +#include +struct X { int a, b; }; +X *make_x() { + // The call to \tcode{std::malloc} implicitly creates an object of type \tcode{X} + // and its subobjects \tcode{a} and \tcode{b}, and returns a pointer to that \tcode{X} object + // (or an object that is pointer-interconvertible\iref{basic.compound} with it), + // in order to give the subsequent class member access operations + // defined behavior. + X *p = (X*)std::malloc(sizeof(struct X)); + p->a = 1; + p->b = 2; + return p; } \end{codeblock} \end{example} \pnum +Except during constant evaluation, +an operation that begins the lifetime of +an array of \tcode{unsigned char} or \tcode{std::byte} +implicitly creates objects within the region of storage occupied by the array. \begin{note} -For purposes of determining -(during parsing) whether an expression is a -\grammarterm{postfix-expression} for a function call, the usual name lookup -rules apply. -In some cases -a name followed by \tcode{<} is treated as a \grammarterm{template-name} -even though name lookup did not find a \grammarterm{template-name} -(see \ref{temp.names}). -For example, -\begin{codeblock} -int h; -void g(); -namespace N { - struct A {}; - template int f(T); - template int g(T); - template int h(T); -} - -int x = f(N::A()); // OK, lookup of \tcode{f} finds nothing, \tcode{f} treated as template name -int y = g(N::A()); // OK, lookup of \tcode{g} finds a function, \tcode{g} treated as template name -int z = h(N::A()); // error: \tcode{h<} does not begin a \grammarterm{template-id} -\end{codeblock} - -The rules have no effect on the syntactic interpretation of an expression. -For example, -\begin{codeblock} -typedef int f; -namespace N { - struct A { - friend void f(A &); - operator int(); - void g(A a) { - int i = f(a); // \tcode{f} is the typedef, not the friend function: equivalent to \tcode{int(a)} - } - }; -} -\end{codeblock} -Because the expression is not a function call, -argument-dependent name lookup does not apply and -the friend function \tcode{f} is not found. +The array object provides storage for these objects. \end{note} - -\pnum -For each argument type \tcode{T} in the function call, -there is a set of zero or more \defnx{associated entities}{entity!associated} -to be considered. -The set of entities is determined entirely by -the types of the function arguments -(and any template template arguments). -Any \grammarterm{typedef-name}s and \grammarterm{using-declaration}{s} -used to specify the types -do not contribute to this set. -The set of entities -is determined in the following way: -\begin{itemize} -\item If \tcode{T} is a fundamental type, its associated set of -entities is empty. - -\item If \tcode{T} is a class type (including unions), -its associated entities are: -the class itself; -the class of which it is a member, if any; -and, if it is a complete type, its direct and indirect base classes. -Furthermore, if \tcode{T} is a class template specialization, -its associated entities also include: -the entities -associated with the types of the template arguments -provided for template type parameters; -the templates used as template template arguments; and -the classes of which any member templates used as template template -arguments are members. +Except during constant evaluation, +any implicit or explicit invocation of a function +named \tcode{\keyword{operator} \keyword{new}} or \tcode{\keyword{operator} \keyword{new}[]} +implicitly creates objects in the returned region of storage and +returns a pointer to a suitable created object. \begin{note} -Non-type template arguments do not -contribute to the set of associated entities. +Some functions in the \Cpp{} standard library implicitly create objects% +\iref{obj.lifetime,c.malloc,mem.res.public,bit.cast,cstring.syn}. \end{note} +\indextext{object model|)} -\item If \tcode{T} is an enumeration type, -its associated entities are \tcode{T} -and, if it is a class member, the member's class. +\rSec2[basic.align]{Alignment} -\item If \tcode{T} is a pointer to \tcode{U} or an array of \tcode{U}, -its associated entities are those associated with \tcode{U}. +\pnum +Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}\iref{basic.fundamental,basic.compound} +which place restrictions on the addresses at which an object of that type +may be allocated. An \defn{alignment} is an \impldef{alignment} +integer value representing the number of bytes between successive addresses +at which a given object can be allocated. An object type imposes an alignment +requirement on every object of that type; stricter alignment can be requested +using the alignment specifier\iref{dcl.align}. +Attempting to create an object\iref{intro.object} in storage that +does not meet the alignment requirements of the object's type +is undefined behavior. -\item If \tcode{T} is a function type, its associated -entities are those associated with the function parameter types and those -associated with the return type. +\pnum +A \defnadj{fundamental}{alignment} is represented by an alignment +less than or equal to the greatest alignment supported by the implementation in +all contexts, which is equal to +\tcode{\keyword{alignof}(std::max_align_t)}\iref{support.types}. +The alignment required for a type may be different when it is used as the type +of a complete object and when it is used as the type of a subobject. +\begin{example} +\begin{codeblock} +struct B { long double d; }; +struct D : virtual B { char c; }; +\end{codeblock} -\item If \tcode{T} is a pointer to a member function of a class -\tcode{X}, its associated entities are those associated -with the function parameter types and return type, together with those -associated with \tcode{X}. +When \tcode{D} is the type of a complete object, it will have a subobject of +type \tcode{B}, so it must be aligned appropriately for a \tcode{\keyword{long} \keyword{double}}. +If \tcode{D} appears as a subobject of another object that also has \tcode{B} +as a virtual base class, the \tcode{B} subobject might be part of a different +subobject, reducing the alignment requirements on the \tcode{D} subobject. +\end{example} +The result of the \keyword{alignof} operator reflects the alignment +requirement of the type in the complete-object case. -\item If \tcode{T} is a pointer to a data member of class \tcode{X}, its -associated entities are those associated with the member -type together with those associated with \tcode{X}. -\end{itemize} -In addition, if the argument is an overload set or the address of such a set, -its associated entities -are the union of those associated with each of the -members of the set, i.e., the entities associated with its -parameter types and return type. -Additionally, if the aforementioned overload set is named with -a \grammarterm{template-id}, its associated entities also include -its template \grammarterm{template-argument}{s} and -those associated with its type \grammarterm{template-argument}s. +\pnum +An \defnadj{extended}{alignment} is represented by an alignment +greater than \tcode{\keyword{alignof}(std::max_align_t)}. It is \impldef{support for extended alignments} +whether any extended alignments are supported and the contexts in which they are +supported\iref{dcl.align}. A type having an extended alignment +requirement is an \defnadj{over-aligned}{type}. +\begin{note} +Every over-aligned type is or contains a class type +to which extended alignment applies (possibly through a non-static data member). +\end{note} +A \defnadj{new-extended}{alignment} is represented by +an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. \pnum -The \term{associated namespaces} for a call are -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 -\begin{itemize} -\item -are found by a search of 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 -\item -are exported, -are attached to a named module \tcode{M}\iref{module.interface}, -do not appear in the translation unit containing the point of the lookup, and -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}, -the above lookup is also performed -from each point in the instantiation context\iref{module.context} of the lookup, -additionally ignoring any declaration that -appears in another translation unit, -is attached to the global module, and -is either discarded\iref{module.global.frag} or has internal linkage. +Alignments are represented as values of the type \tcode{std::size_t}. +Valid alignments include only those values returned by an \keyword{alignof} +expression for the fundamental types plus an additional \impldef{alignment additional +values} +set of values, which may be empty. +Every alignment value shall be a non-negative integral power of two. \pnum -\begin{example} -\begin{codeblocktu}{Translation unit \#1} -export module M; -namespace R { - export struct X {}; - export void f(X); -} -namespace S { - export void f(R::X, R::X); -} -\end{codeblocktu} +Alignments have an order from \defnx{weaker}{alignment!weaker} to +\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter +alignments have larger alignment values. An address that satisfies an alignment +requirement also satisfies any weaker valid alignment requirement. -\begin{codeblocktu}{Translation unit \#2} -export module N; -import M; -export R::X make(); -namespace R { static int g(X); } -export template void apply(T t, U u) { - f(t, u); - g(t); -} -\end{codeblocktu} +\pnum +The alignment requirement of a complete type can be queried using an +\keyword{alignof} expression\iref{expr.alignof}. Furthermore, +the narrow character types\iref{basic.fundamental} shall have the weakest +alignment requirement. +\begin{note} +This enables the ordinary character types to be used as the +underlying type for an aligned memory area\iref{dcl.align}. +\end{note} -\begin{codeblocktu}{Translation unit \#3} -module Q; -import N; -namespace S { - struct Z { template operator T(); }; -} -void test() { - auto x = make(); // OK, \tcode{decltype(x)} is \tcode{R::X} in module \tcode{M} - R::f(x); // error: \tcode{R} and \tcode{R::f} are not visible here - f(x); // OK, calls \tcode{R::f} from interface of \tcode{M} - f(x, S::Z()); // error: \tcode{S::f} in module \tcode{M} not considered - // even though \tcode{S} is an associated namespace - apply(x, S::Z()); // error: \tcode{S::f} is visible in instantiation context, but - // \tcode{R::g} has internal linkage and cannot be used outside TU \#2 -} -\end{codeblocktu} -\end{example} +\pnum +Comparing alignments is meaningful and provides the obvious results: + +\begin{itemize} +\item Two alignments are equal when their numeric values are equal. +\item Two alignments are different when their numeric values are not equal. +\item When an alignment is larger than another it represents a stricter alignment. +\end{itemize} \pnum \begin{note} -The associated namespace can include namespaces -already considered by ordinary unqualified lookup. +The runtime pointer alignment function\iref{ptr.align} +can be used to obtain an aligned pointer within a buffer; +an \grammarterm{alignment-specifier}\iref{dcl.align} +can be used to align storage explicitly. \end{note} -\begin{example} -\begin{codeblock} -namespace NS { - class T { }; - void f(T); - void g(T, int); -} -NS::T parm; -void g(NS::T, float); -int main() { - f(parm); // OK, calls \tcode{NS::f} - extern void g(NS::T, float); - g(parm, 1); // OK, calls \tcode{g(NS::T, float)} -} -\end{codeblock} -\end{example} -\rSec2[basic.lookup.qual]{Qualified name lookup} +\pnum +If a request for a specific extended alignment in a specific context is not +supported by an implementation, the program is ill-formed. -\rSec3[basic.lookup.qual.general]{General} +\rSec2[basic.life]{Lifetime} \pnum -\indextext{lookup!qualified name|(}% -\indextext{name!qualified}% -\indextext{qualification!explicit}% -Lookup of an \grammarterm{identifier} -followed by a \tcode{::} scope resolution operator -considers only -namespaces, types, and templates whose specializations are types. -If a name, \grammarterm{template-id}, or \grammarterm{computed-type-specifier} -is followed by a \tcode{::}, -it shall designate a namespace, class, enumeration, or dependent type, -and the \tcode{::} is never interpreted as -a complete \grammarterm{nested-name-specifier}. +In this subclause, ``before'' and ``after'' refer to the ``happens before'' +relation\iref{intro.multithread}. + +\pnum +\indextext{object lifetime|(}% +The \defn{lifetime} of an object or reference is a runtime property of the +object or reference. +A variable is said to have \defnadj{vacuous}{initialization} +if it is default-initialized, no other initialization is performed, and, +if it is of class type or a (possibly multidimensional) array thereof, +a trivial constructor of that class type is selected for +the default-initialization. +The lifetime of an object of type \tcode{T} begins when: +\begin{itemize} +\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}, +\end{itemize} +except that if the object is a union member or subobject thereof, +its lifetime only begins if that union member is the +initialized member in the union\iref{dcl.init.aggr,class.base.init}, +or as described in +\ref{class.union}, \ref{class.copy.ctor}, and \ref{class.copy.assign}, +and except as described in \ref{allocator.members}. +The lifetime of an object \placeholder{o} of type \tcode{T} ends when: +\begin{itemize} +\item if \tcode{T} is a non-class type, the object is destroyed, or +\item if \tcode{T} is a class type, the destructor call starts, or +\item the storage which the object occupies is released, +or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. +\end{itemize} +When evaluating a \grammarterm{new-expression}, +storage is considered reused after it is returned from the allocation function, +but before the evaluation of the \grammarterm{new-initializer}\iref{expr.new}. \begin{example} \begin{codeblock} -class A { -public: - static int n; +struct S { + int m; }; -int main() { - int A; - A::n = 42; // OK - A b; // error: \tcode{A} does not name a type -} -template struct B : A {}; -namespace N { - template void B(); - int f() { - return B<0>::n; // error: \tcode{N::B<0>} is not a type - } + +void f() { + S x{1}; + new(&x) S(x.m); // undefined behavior } \end{codeblock} \end{example} -\indextext{operator!scope resolution}% -\indextext{scope resolution operator|see{operator, scope resolution}}% +\pnum +\indextext{reference lifetime}% +The lifetime of a reference begins when its initialization is complete. +The lifetime of a reference ends as if it were a scalar object requiring storage. \pnum -A member-qualified name is -the (unique) component name\iref{expr.prim.id.unqual}, if any, of -\begin{itemize} -\item -an \grammarterm{unqualified-id} or -\item -a \grammarterm{nested-name-specifier} of the form -\grammarterm{type-name} \tcode{::} or \grammarterm{namespace-name} \tcode{::} -\end{itemize} -in the \grammarterm{id-expression} of a class member access expression\iref{expr.ref}. -A \defnadj{qualified}{name} is -\begin{itemize} -\item a member-qualified name or -\item the terminal name of -\begin{itemize} -\item a \grammarterm{qualified-id}, -\item a \grammarterm{using-declarator}, -\item a \grammarterm{typename-specifier}, -\item a \grammarterm{qualified-namespace-specifier}, or -\item a \grammarterm{nested-name-specifier}, -\grammarterm{elaborated-type-specifier}, or -\grammarterm{class-or-decltype} -that has a \grammarterm{nested-name-specifier}\iref{expr.prim.id.qual}. -\end{itemize} -\end{itemize} -The \defn{lookup context} of a member-qualified name is -the type of its associated object expression -(considered dependent if the object expression is type-dependent). -The lookup context of any other qualified name is -the type, template, or namespace -nominated by the preceding \grammarterm{nested-name-specifier}. \begin{note} -When parsing a class member access, -the name following the \tcode{->} or \tcode{.} is -a qualified name even though it is not yet known of which kind. +\ref{class.base.init} +describes the lifetime of base and member subobjects. \end{note} -\begin{example} -In -\begin{codeblock} - N::C::m.Base::f() -\end{codeblock} -\tcode{Base} is a member-qualified name; -the other qualified names are \tcode{C}, \tcode{m}, and \tcode{f}. -\end{example} \pnum -\defnx{Qualified name lookup}{lookup!qualified name} -in a class, namespace, or enumeration performs -a search of the scope associated with it\iref{class.member.lookup} -except as specified below. -Unless otherwise specified, -a qualified name undergoes qualified name lookup in its lookup context -from the point where it appears -unless the lookup context either -is dependent and is not the current instantiation\iref{temp.dep.type} or -is not a class or class template. -If nothing is found by qualified lookup for a member-qualified name -that is the terminal name\iref{expr.prim.id.unqual} of -a \grammarterm{nested-name-specifier} and -is not dependent, it undergoes unqualified lookup. +The properties ascribed to objects and references throughout this document +apply for a given object or reference only during its lifetime. \begin{note} -During lookup for a template specialization, no names are dependent. +In particular, before the lifetime of an object starts and after its +lifetime ends there are significant restrictions on the use of the +object, as described below, in~\ref{class.base.init}, and +in~\ref{class.cdtor}. Also, the behavior of an object under construction +and destruction can differ from the behavior of an object whose +lifetime has started and not ended. \ref{class.base.init} +and~\ref{class.cdtor} describe the behavior of an object during its periods +of construction and destruction. \end{note} -\begin{example} -\begin{codeblock} -int f(); -struct A { - int B, C; - template using D = void; - using T = void; - void f(); -}; -using B = A; -template using C = A; -template using D = A; -template using X = A; -template -void g(T *p) { // as instantiated for \tcode{g}: - p->X<0>::f(); // error: \tcode{A::X} not found in \tcode{((p->X) < 0) > ::f()} - p->template X<0>::f(); // OK, \tcode{::X} found in definition context - p->B::f(); // OK, non-type \tcode{A::B} ignored - p->template C<0>::f(); // error: \tcode{A::C} is not a template - p->template D<0>::f(); // error: \tcode{A::D<0>} is not a class type - p->T::f(); // error: \tcode{A::T} is not a class type -} -template void g(A*); -\end{codeblock} -\end{example} +\pnum +A program may end the lifetime of an object of class type without invoking the +destructor, by reusing or releasing the storage as described above. +\begin{note} +A \grammarterm{delete-expression}\iref{expr.delete} invokes the destructor +prior to releasing the storage. +\end{note} +In this case, the destructor is not implicitly invoked. +\begin{note} +The correct behavior of a program often depends on +the destructor being invoked for each object of class type. +\end{note} \pnum -If a qualified name $Q$ follows a \tcode{\~}: +Before the lifetime of an object has started but after the storage which +the object will occupy has been allocated +\begin{footnote} +For example, before the dynamic initialization of +an object with static storage duration\iref{basic.start.dynamic}. + +\end{footnote} +or, after the lifetime of an object has ended and before the storage +which the object occupied is reused or released, any pointer that represents the address of +the storage location where the object will be or was located may be +used but only in limited ways. +For an object under construction or destruction, see~\ref{class.cdtor}. +Otherwise, such +a pointer refers to allocated +storage\iref{basic.stc.dynamic.allocation}, and using the pointer as +if the pointer were of type \tcode{\keyword{void}*} is +well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in +limited ways, as described below. The +program has undefined behavior if \begin{itemize} \item -If $Q$ is a member-qualified name, -it undergoes unqualified lookup as well as qualified lookup. -\item -Otherwise, its \grammarterm{nested-name-specifier} $N$ shall nominate a type. -If $N$ has another \grammarterm{nested-name-specifier} $S$, -$Q$ is looked up as if its lookup context were that nominated by $S$. + the pointer is used as the operand of a \grammarterm{delete-expression}, \item -Otherwise, if the terminal name of $N$ is a member-qualified name $M$, -$Q$ is looked up as if $\tcode{\~}Q$ appeared in place of $M$ (as above). + the pointer is used to access a non-static data member or call a + non-static member function of the object, or \item -Otherwise, $Q$ undergoes unqualified lookup. + the pointer is implicitly converted\iref{conv.ptr} to a pointer + to a virtual base class, or \item -Each lookup for $Q$ considers only -types (if $Q$ is not followed by a \tcode{<}) and -templates whose specializations are types. -If it finds nothing or is ambiguous, it is discarded. + the pointer is used as the operand of a + \keyword{static_cast}\iref{expr.static.cast}, except when the conversion + is to pointer to \cv{}~\keyword{void}, or to pointer to \cv{}~\keyword{void} + and subsequently to pointer to + \cv{}~\keyword{char}, + \cv{}~\tcode{\keyword{unsigned} \keyword{char}}, or + \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or \item -The \grammarterm{type-name} that is or contains $Q$ -shall refer to its (original) lookup context (ignoring cv-qualification) under -the interpretation established by at least one (successful) lookup performed. + the pointer is used as the operand of a + \keyword{dynamic_cast}\iref{expr.dynamic.cast}. \end{itemize} \begin{example} \begin{codeblock} -struct C { - typedef int I; -}; -typedef int I1, I2; -extern int* p; -extern int* q; -void f() { - p->C::I::~I(); // \tcode{I} is looked up in the scope of \tcode{C} - q->I1::~I2(); // \tcode{I2} is found by unqualified lookup -} -struct A { - ~A(); +#include + +struct B { + virtual void f(); + void mutate(); + virtual ~B(); }; -typedef A AB; -int main() { - AB* p; - p->AB::~AB(); // explicitly calls the destructor for \tcode{A} -} -\end{codeblock} -\end{example} -\rSec3[class.qual]{Class members} +struct D1 : B { void f(); }; +struct D2 : B { void f(); }; -\indextext{lookup!class member}% +void B::mutate() { + new (this) D2; // reuses storage --- ends the lifetime of \tcode{*this} + f(); // undefined behavior + ... = this; // OK, \keyword{this} points to valid memory +} -\pnum -In a lookup for a qualified name $N$ whose lookup context is a class $C$ -in which function names are not ignored, -\begin{footnote} -Lookups in which -function names are ignored include names appearing in a -\grammarterm{nested-name-specifier}, an -\grammarterm{elaborated-type-specifier}, or a \grammarterm{base-specifier}. -\end{footnote} -\begin{itemize} -\item -if the search finds the injected-class-name of \tcode{C}\iref{class.pre}, or -\item -if $N$ is dependent and -is the terminal name of a \grammarterm{using-declarator}\iref{namespace.udecl} -that names a constructor, -\end{itemize} -$N$ is instead considered to name the constructor of class \tcode{C}. -Such a constructor name shall be used only -in the \grammarterm{declarator-id} of a (friend) declaration of a constructor or -in a \grammarterm{using-declaration}. -\begin{example} -\begin{codeblock} -struct A { A(); }; -struct B: public A { B(); }; - -A::A() { } -B::B() { } - -B::A ba; // object of type \tcode{A} -A::A a; // error: \tcode{A::A} is not a type name -struct A::A a2; // object of type \tcode{A} +void g() { + void* p = std::malloc(sizeof(D1) + sizeof(D2)); + B* pb = new (p) D1; + pb->mutate(); + *pb; // OK, \tcode{pb} points to valid memory + void* q = pb; // OK, \tcode{pb} points to valid memory + pb->f(); // undefined behavior: lifetime of \tcode{*pb} has ended +} \end{codeblock} \end{example} -\rSec3[namespace.qual]{Namespace members} - \pnum -Qualified name lookup in a namespace $N$ additionally searches -every element of the inline namespace set of $N$\iref{namespace.def}. -If nothing is found, -the results of the lookup are the results of qualified name lookup -in each namespace nominated by a \grammarterm{using-directive} -that precedes the point of the lookup and -inhabits $N$ or an element of $N$'s inline namespace set. +Similarly, before the lifetime of an object has started but after the +storage which the object will occupy has been allocated or, after the +lifetime of an object has ended and before the storage which the object +occupied is reused or released, any glvalue that refers to the original +object may be used but only in limited ways. +For an object under construction or destruction, see~\ref{class.cdtor}. +Otherwise, such +a glvalue refers to +allocated storage\iref{basic.stc.dynamic.allocation}, and using the +properties of the glvalue that do not depend on its value is +well-defined. The program has undefined behavior if +\begin{itemize} +\item the glvalue is used to access the object, or +\item the glvalue is used to call a non-static member function of the object, or +\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or +\item the glvalue is used as the operand of a +\keyword{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of +\keyword{typeid}. +\end{itemize} + \begin{note} -If a \grammarterm{using-directive} refers to a namespace -that has already been considered, it does not affect the result. +Therefore, undefined behavior results +if an object that is being constructed in one thread is referenced from another +thread without adequate synchronization. \end{note} -\begin{example} -\begin{codeblock} -int x; -namespace Y { - void f(float); - void h(int); -} - -namespace Z { - void h(double); -} - -namespace A { - using namespace Y; - void f(int); - void g(int); - int i; -} -namespace B { - using namespace Z; - void f(char); - int i; -} +\pnum +An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if +\begin{itemize} +\item the storage that $o_2$ occupies exactly overlays +the storage that $o_1$ occupied, and -namespace AB { - using namespace A; - using namespace B; - void g(); -} +\item $o_1$ and $o_2$ are of the same type +(ignoring the top-level cv-qualifiers), and -void h() -{ - AB::g(); // \tcode{g} is declared directly in \tcode{AB}, therefore \tcode{S} is $\{ \tcode{AB::g()} \}$ and \tcode{AB::g()} is chosen +\item $o_1$ is not a const, complete object, and - AB::f(1); // \tcode{f} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}; - // namespace \tcode{Y} is not searched and \tcode{Y::f(float)} is not considered; - // \tcode{S} is $\{ \tcode{A::f(int)}, \tcode{B::f(char)} \}$ and overload resolution chooses \tcode{A::f(int)} +\item neither $o_1$ nor $o_2$ +is a potentially-overlapping subobject\iref{intro.object}, and - AB::f('c'); // as above but resolution chooses \tcode{B::f(char)} +\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$. +\end{itemize} - AB::x++; // \tcode{x} is not declared directly in \tcode{AB}, and is not declared in \tcode{A} or \tcode{B}, so the rules - // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \}$ so the program is ill-formed +\pnum +After the lifetime of an object has ended and before the storage which the +object occupied is reused or released, if a new object is created at the +storage location which the original object occupied and the original object was +transparently replaceable by the new object, a pointer that pointed to the +original object, a reference that referred to the original object, or the name +of the original object will automatically refer to the new object and, once the +lifetime of the new object has started, can be used to manipulate the new +object. - AB::i++; // \tcode{i} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}, - // \tcode{S} is $\{ \tcode{A::i}, \tcode{B::i} \}$ so the use is ambiguous and the program is ill-formed +\begin{example} +\begin{codeblock} +struct C { + int i; + void f(); + const C& operator=( const C& ); +}; - AB::h(16.8); // \tcode{h} is not declared directly in \tcode{AB} and not declared directly in \tcode{A} or \tcode{B} so the rules - // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \tcode{Y::h(int)}, \tcode{Z::h(double)} \}$ and - // overload resolution chooses \tcode{Z::h(double)} +const C& C::operator=( const C& other) { + if ( this != &other ) { + this->~C(); // lifetime of \tcode{*this} ends + new (this) C(other); // new object of type \tcode{C} created + f(); // well-defined + } + return *this; } + +C c1; +C c2; +c1 = c2; // well-defined +c1.f(); // well-defined; \tcode{c1} refers to a new object of type \tcode{C} \end{codeblock} \end{example} +\begin{note} +If these conditions are not met, +a pointer to the new object can be obtained from +a pointer that represents the address of its storage +by calling \tcode{std::launder}\iref{ptr.launder}. +\end{note} \pnum -\begin{note} -The same declaration found more than once is not an ambiguity (because -it is still a unique declaration). +If a program ends the lifetime of an object of type \tcode{T} with +static\iref{basic.stc.static}, thread\iref{basic.stc.thread}, +or automatic\iref{basic.stc.auto} +storage duration and if \tcode{T} has a non-trivial destructor, +\begin{footnote} +That +is, an object for which a destructor will be called +implicitly---upon exit from the block for an object with +automatic storage duration, upon exit from the thread for an object with +thread storage duration, or upon exit from the program for an object +with static storage duration. +\end{footnote} +and another object of the original type does not occupy +that same storage location when the implicit destructor call takes +place, the behavior of the program is undefined. This is true +even if the block is exited with an exception. \begin{example} \begin{codeblock} -namespace A { - int a; -} - -namespace B { - using namespace A; -} - -namespace C { - using namespace A; -} - -namespace BC { - using namespace B; - using namespace C; -} - -void f() -{ - BC::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ -} - -namespace D { - using A::a; -} - -namespace BD { - using namespace B; - using namespace D; -} +class T { }; +struct B { + ~B(); +}; -void g() -{ - BD::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ -} +void h() { + B b; + new (&b) T; +} // undefined behavior at block exit \end{codeblock} \end{example} -\end{note} \pnum +Creating a new object within the storage that a const, complete +object with static, thread, or automatic storage duration occupies, +or within the storage that such a const object used to occupy before +its lifetime ended, results in undefined behavior. \begin{example} -Because each referenced namespace is searched at most once, the -following is well-defined: \begin{codeblock} -namespace B { - int b; -} - -namespace A { - using namespace B; - int a; -} +struct B { + B(); + ~B(); +}; -namespace B { - using namespace A; -} +const B b; -void f() -{ - A::a++; // OK, \tcode{a} declared directly in \tcode{A}, \tcode{S} is $\{ \tcode{A::a} \}$ - B::a++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{A::a} \}$ - A::b++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{B::b} \}$ - B::b++; // OK, \tcode{b} declared directly in \tcode{B}, \tcode{S} is $\{ \tcode{B::b} \}$ +void h() { + b.~B(); + new (const_cast(&b)) const B; // undefined behavior } \end{codeblock} \end{example} +\indextext{object lifetime|)} + +\rSec2[basic.indet]{Indeterminate and erroneous values} \pnum +When storage for an object with automatic or dynamic storage duration +is obtained, +the bytes comprising the storage for the object +have the following initial value: +\begin{itemize} +\item +If the object has dynamic storage duration, or +is the object associated with a variable or function parameter +whose first declaration is marked with +the \tcode{[[indeterminate]]} attribute\iref{dcl.attr.indet}, +the bytes have \defnadjx{indeterminate}{values}{value}; +\item +otherwise, the bytes have \defnadjx{erroneous}{values}{value}, +where each value is determined by the implementation +independently of the state of the program. +\end{itemize} +If no initialization is performed for an object (including subobjects), +such a byte retains its initial value +until that value is replaced\iref{dcl.init.general,expr.ass}. +If any bit in the value representation has an indeterminate value, +the object has an indeterminate value; +otherwise, if any bit in the value representation has an erroneous value, +the object has an erroneous value\iref{conv.lval}. \begin{note} -Class and enumeration declarations are not discarded -because of other declarations found in other searches. +Objects with static or thread storage duration are zero-initialized, +see~\ref{basic.start.static}. \end{note} + +\pnum +Except in the following cases, +if an indeterminate value is produced by an evaluation, +the behavior is undefined, and +if an erroneous value is produced by an evaluation, +the behavior is erroneous and +the result of the evaluation is the value so produced but is not erroneous: +\begin{itemize} +\item + If an indeterminate or erroneous value of + unsigned ordinary character type\iref{basic.fundamental} + or \tcode{std::byte} type\iref{cstddef.syn} + is produced by the evaluation of: + \begin{itemize} + \item + the second or third operand of a conditional expression\iref{expr.cond}, + \item + the right operand of a comma expression\iref{expr.comma}, + \item + the operand of a cast or conversion\iref{conv.integral, + expr.type.conv,expr.static.cast,expr.cast} + to an unsigned ordinary character type + or \tcode{std::byte} type\iref{cstddef.syn}, or + \item + a discarded-value expression\iref{expr.context}, + \end{itemize} + then the result of the operation is an indeterminate value or + that erroneous value, respectively. +\item + If an indeterminate or erroneous value of + unsigned ordinary character type or \tcode{std::byte} type + is produced by the evaluation of + the right operand of a simple assignment operator\iref{expr.ass} + whose first operand is an lvalue of + unsigned ordinary character type or \tcode{std::byte} type, + an indeterminate value or that erroneous value, respectively, replaces + the value of the object referred to by the left operand. +\item + If an indeterminate or erroneous value of unsigned ordinary character type + is produced by the evaluation of the initialization expression + when initializing an object of unsigned ordinary character type, + that object is initialized to an indeterminate + value or that erroneous value, respectively. +\item + If an indeterminate value of + unsigned ordinary character type or \tcode{std::byte} type + is produced by the evaluation of the initialization expression + when initializing an object of \tcode{std::byte} type, + that object is initialized to an indeterminate value or + that erroneous value, respectively. +\end{itemize} +Converting an indeterminate or erroneous value of +unsigned ordinary character type or \tcode{std::byte} type +produces an indeterminate or erroneous value, respectively. +In the latter case, +the result of the conversion is the value of the converted operand. \begin{example} \begin{codeblock} -namespace A { - struct x { }; - int x; - int y; +int f(bool b) { + unsigned char *c = new unsigned char; + unsigned char d = *c; // OK, \tcode{d} has an indeterminate value + int e = d; // undefined behavior + return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} } -namespace B { - struct y { }; +int g(bool b) { + unsigned char c; + unsigned char d = c; // no erroneous behavior, but \tcode{d} has an erroneous value + + assert(c == d); // holds, both integral promotions have erroneous behavior + + int e = d; // erroneous behavior + return b ? d : 0; // erroneous behavior if \tcode{b} is \tcode{true} } -namespace C { - using namespace A; - using namespace B; - int i = C::x; // OK, \tcode{A::x} (of type \tcode{int}) - int j = C::y; // ambiguous, \tcode{A::y} or \tcode{B::y} +void h() { + int d1, d2; + + int e1 = d1; // erroneous behavior + int e2 = d1; // erroneous behavior + + assert(e1 == e2); // holds + assert(e1 == d1); // holds, erroneous behavior + assert(e2 == d1); // holds, erroneous behavior + + std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but \tcode{d2} has an erroneous value + assert(e1 == d2); // holds, erroneous behavior + assert(e2 == d2); // holds, erroneous behavior } \end{codeblock} \end{example} -\indextext{lookup!qualified name|)}% +\rSec2[basic.stc]{Storage duration} -\rSec2[basic.lookup.elab]{Elaborated type specifiers}% -\indextext{lookup!elaborated type specifier|(}% -\indextext{type specifier!elaborated} +\rSec3[basic.stc.general]{General} \pnum -If the \grammarterm{class-key} or \keyword{enum} keyword -in an \grammarterm{elaborated-type-specifier} -is followed by an \grammarterm{identifier} -that is not followed by \tcode{::}, -lookup for the \grammarterm{identifier} is type-only\iref{basic.lookup.general}. +\indextext{storage duration|(}% +The \defn{storage duration} is the property of an object that defines the minimum +potential lifetime of the storage containing the object. The storage +duration is determined by the construct used to create the object and is +one of the following: +\begin{itemize} +\item static storage duration +\item thread storage duration +\item automatic storage duration +\item dynamic storage duration +\end{itemize} \begin{note} -In general, the recognition of an \grammarterm{elaborated-type-specifier} -depends on the following tokens. -If the \grammarterm{identifier} is followed by \tcode{::}, -see \ref{basic.lookup.qual}. +After the duration of a region of storage has ended, +the use of pointers to that region of storage is limited\iref{basic.compound}. \end{note} \pnum -If the terminal name of the \grammarterm{elaborated-type-specifier} -is a qualified name, -lookup for it is type-only. -If the name lookup does not find a previously declared \grammarterm{type-name}, -the \grammarterm{elaborated-type-specifier} is ill-formed. +\indextext{storage duration!static}% +\indextext{storage duration!thread}% +\indextext{storage duration!automatic}% +\indextext{storage duration!dynamic}% +Static, thread, and automatic storage durations are associated with objects +introduced by declarations\iref{basic.def} and +with temporary objects\iref{class.temporary}. +The dynamic storage duration +is associated with objects created by a +\grammarterm{new-expression}\iref{expr.new} or +with implicitly created objects\iref{intro.object}. \pnum -\begin{example} -\begin{codeblock} -struct Node { - struct Node* Next; // OK, refers to injected-class-name \tcode{Node} - struct Data* Data; // OK, declares type \tcode{Data} at global scope and member \tcode{Data} -}; +The storage duration categories apply to references as well. -struct Data { - struct Node* Node; // OK, refers to \tcode{Node} at global scope - friend struct ::Glob; // error: \tcode{Glob} is not declared, cannot introduce a qualified type\iref{dcl.type.elab} - friend struct Glob; // OK, refers to (as yet) undeclared \tcode{Glob} at global scope. - @\commentellip@ -}; +\pnum +\indextext{storage duration!class member}% +The storage duration of subobjects and reference members +is that of their complete object\iref{intro.object}. +\indextext{storage duration|)}% -struct Base { - struct Data; // OK, declares nested \tcode{Data} - struct ::Data* thatData; // OK, refers to \tcode{::Data} - struct Base::Data* thisData; // OK, refers to nested \tcode{Data} - friend class ::Data; // OK, global \tcode{Data} is a friend - friend class Data; // OK, nested \tcode{Data} is a friend - struct Data { @\commentellip@ }; // Defines nested \tcode{Data} -}; +\rSec3[basic.stc.static]{Static storage duration} -struct Data; // OK, redeclares \tcode{Data} at global scope -struct ::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} -struct Base::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} -struct Base::Datum; // error: \tcode{Datum} undefined -struct Base::Data* pBase; // OK, refers to nested \tcode{Data} -\end{codeblock} -\end{example} -\indextext{lookup!elaborated type specifier|)}% +\pnum +All variables which +\begin{itemize} +\item +do not have thread storage duration and +\item +belong to a namespace scope\iref{basic.scope.namespace} or +are first declared with +the \keyword{static} or \keyword{extern} keywords\iref{dcl.stc} +\end{itemize} +have \defnadj{static}{storage duration}. +The storage for these entities lasts for the duration of the +program\iref{basic.start.static,basic.start.term}. -\rSec2[basic.lookup.udir]{Using-directives and namespace aliases} +\pnum +If a variable with static storage duration has initialization or a +destructor with side effects, it shall not be eliminated even if it +appears to be unused, except that a class object or its copy/move may be +eliminated as specified in~\ref{class.copy.elision}. \pnum -\indextext{lookup!using-directives and}% -\indextext{lookup!namespace aliases and}% -In a \grammarterm{using-directive} or \grammarterm{namespace-alias-definition}, -during the lookup for a \grammarterm{namespace-name} or for a name in a -\grammarterm{nested-name-specifier}{} -only namespace names are considered.% -\indextext{lookup!name|)}% +\begin{note} +\indextext{object!local static@local \tcode{static}}% +The keyword \keyword{static} can be used to declare +a block variable\iref{basic.scope.block} with static storage duration; +\ref{stmt.dcl} and \ref{basic.start.term} describe the +initialization and destruction of such variables. +\indextext{member!class static@class \tcode{static}}% +The keyword \keyword{static} applied to +a class data member in a class definition +gives the data member static storage duration\iref{class.static.data}. +\end{note} -\rSec1[basic.link]{Program and linkage}% -\indextext{linkage|(} +\rSec3[basic.stc.thread]{Thread storage duration} \pnum -\indextext{program}% -A \defn{program} consists of one or more translation units\iref{lex.separate} -linked together. A translation unit consists -of a sequence of declarations. - -\begin{bnf} -\nontermdef{translation-unit}\br - \opt{declaration-seq}\br - \opt{global-module-fragment} module-declaration \opt{declaration-seq} \opt{private-module-fragment} -\end{bnf} +All variables declared with the \keyword{thread_local} keyword have +\defnadj{thread}{storage duration}. +The storage for these entities lasts for the duration of +the thread in which they are created. There is a distinct object or reference +per thread, and use of the declared name refers to the entity associated with +the current thread. \pnum -\indextext{translation unit}% -A name can have -\defnadj{external}{linkage}, -\defnadj{module}{linkage}, -\defnadj{internal}{linkage}, or -\defnadj{no}{linkage}, -as determined by the rules below. \begin{note} -All declarations of an entity with a name with internal linkage -appear in the same translation unit. -All declarations of an entity with module linkage -are attached to the same module. +A variable with thread storage duration is initialized as specified +in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and \ref{stmt.dcl} +and, if constructed, is destroyed on thread exit\iref{basic.start.term}. \end{note} +\rSec3[basic.stc.auto]{Automatic storage duration} + \pnum -\indextext{linkage!\idxcode{static} and}% -\indextext{\idxcode{static}!linkage of}% -\indextext{linkage!\idxcode{const} and}% -\indextext{\idxcode{const}!linkage of}% -\indextext{linkage!\idxcode{inline} and}% -\indextext{\idxcode{inline}!linkage of}% -The name of an entity -that belongs to a namespace scope\iref{basic.scope.namespace} -has internal linkage if it is the name of -\begin{itemize} -\item - a variable, variable template, function, or function template that is - explicitly declared \keyword{static}; or -\item - a non-template variable of non-volatile const-qualified type, unless - \begin{itemize} - \item it is declared in the purview of a module interface unit - (outside the \grammarterm{private-module-fragment}, if any) or - module partition, or - \item it is explicitly declared \keyword{extern}, or - \item it is inline, or - \item it was previously declared and the prior declaration did - not have internal linkage; or - \end{itemize} -\item - a data member of an anonymous union. -\end{itemize} +\indextext{storage duration!local object}% +Variables that belong to a block scope and are +not explicitly declared \keyword{static}, \keyword{thread_local}, or \keyword{extern} have +\defnadj{automatic}{storage duration}. The storage +for such variables lasts until the block in which they are created exits. \begin{note} -An instantiated variable template that has const-qualified type -can have external or module linkage, even if not declared \keyword{extern}. +These variables are initialized and destroyed as described in~\ref{stmt.dcl}. \end{note} +Variables that belong to a parameter scope also have automatic storage duration. +The storage for a function parameter lasts until +immediately after its destruction\iref{expr.call}. \pnum -An unnamed namespace or a namespace declared directly or indirectly within an -unnamed namespace has internal linkage. All other namespaces have external linkage. -The name of an entity that belongs to a namespace scope -that has not been given internal linkage above -and that is the name of -\begin{itemize} -\item a variable; or -\item a function; or -\item -\indextext{class!linkage of}% -a named class\iref{class.pre}, or an unnamed class defined in a -typedef declaration in which the class has the typedef name for linkage -purposes\iref{dcl.typedef}; or -\item -\indextext{enumeration!linkage of}% -a named enumeration\iref{dcl.enum}, or an unnamed enumeration defined -in a typedef declaration in which the enumeration has the typedef name -for linkage purposes\iref{dcl.typedef}; or -\item an unnamed enumeration -that has an enumerator as a name for linkage purposes\iref{dcl.enum}; or -\item a template -\end{itemize} -has its linkage determined as follows: -\begin{itemize} -\item -\indextext{friend function!linkage of}% -if the entity is a function or function template -first declared in a friend declaration and -that declaration is a definition and -the enclosing class is defined within an \grammarterm{export-declaration}, -the name has the same linkage, if any, -as the name of the enclosing class\iref{class.friend}; -\item -otherwise, -\indextext{friend function!linkage of}% -if the entity is a function or function template -declared in a friend declaration and -a corresponding non-friend declaration is reachable, -%FIXME: Which declaration is "that prior declaration"? -%FIXME: "prior" with respect to what? And what about dependent lookup? -the name has the linkage determined from that prior declaration, -\item -otherwise, -if the enclosing namespace has internal linkage, -the name has internal linkage; -\item -otherwise, -if the declaration of the name is -attached to a named module\iref{module.unit} -and is not exported\iref{module.interface}, -the name has module linkage; -\item -otherwise, -the name has external linkage. -\end{itemize} - -\pnum -In addition, -a member function, -a static data member, -a named class or enumeration that inhabits a class scope, or -an unnamed class or enumeration defined in a typedef declaration -that inhabits a class scope -such that the class or enumeration -has the typedef name for linkage purposes\iref{dcl.typedef}, -has the same linkage, if any, as the name of the class of which it is a member. +If a variable with automatic storage duration has initialization or a destructor with side +effects, an implementation shall not destroy it before the end of its block +nor eliminate it as an optimization, even if it appears to be +unused, except that a class object or its copy/move may be eliminated as +specified in~\ref{class.copy.elision}. -\pnum -\begin{example} -\begin{codeblock} -static void f(); -extern "C" void h(); -static int i = 0; // \#1 -void q() { - extern void f(); // internal linkage - extern void g(); // \tcode{::g}, external linkage - extern void h(); // C language linkage - int i; // \#2: \tcode{i} has no linkage - { - extern void f(); // internal linkage - extern int i; // \#3: internal linkage - } -} -\end{codeblock} -Even though the declaration at line \#2 hides the declaration at line \#1, -the declaration at line \#3 still redeclares \#1 and receives internal linkage. -\end{example} +\rSec3[basic.stc.dynamic]{Dynamic storage duration}% -\pnum -\indextext{linkage!no}% -Names not covered by these rules have no linkage. Moreover, except as -noted, a name declared at block scope\iref{basic.scope.block} has no -linkage. +\rSec4[basic.stc.dynamic.general]{General}% +\indextext{storage duration!dynamic|(} \pnum -Two declarations of entities declare the same entity -if, considering declarations of unnamed types to introduce their names -for linkage purposes, if any\iref{dcl.typedef,dcl.enum}, -they correspond\iref{basic.scope.scope}, -have the same target scope that is not a function or template parameter scope, -neither is a name-independent declaration, -and either -\begin{itemize} -\item -they appear in the same translation unit, or -\item -they both declare names with module linkage and are attached to the same module, or -\item -they both declare names with external linkage. -\end{itemize} +Objects can be created dynamically during program +execution\iref{intro.execution}, using +\indextext{\idxcode{new}}% +\grammarterm{new-expression}{s}\iref{expr.new}, and destroyed using +\indextext{\idxcode{delete}}% +\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp{} implementation +provides access to, and management of, dynamic storage via +the global \defnx{allocation functions}{allocation function} +\tcode{\keyword{operator} \keyword{new}} and +\tcode{\keyword{operator} \keyword{new}[]} and +the global \defnx{deallocation functions}{deallocation function} +\tcode{\keyword{operator} \keyword{delete}} and +\tcode{\keyword{operator} \keyword{delete}[]}. \begin{note} -There are other circumstances in which declarations declare the same entity% -\iref{dcl.link,temp.type,temp.spec.partial}. +The non-allocating forms described in \ref{new.delete.placement} +do not perform allocation or deallocation. \end{note} \pnum -If a declaration $H$ that declares a name with internal linkage -precedes a declaration $D$ in another translation unit $U$ and -would declare the same entity as $D$ if it appeared in $U$, -the program is ill-formed. +The library provides default definitions for the global allocation and +deallocation functions. Some global allocation and deallocation +functions are replaceable\iref{new.delete}; +these are attached to the global module\iref{module.unit}. +A \Cpp{} program shall +provide at most one definition of a replaceable allocation or +deallocation function. Any such function definition replaces the default +version provided in the library\iref{replacement.functions}. The +following allocation and deallocation functions\iref{support.dynamic} +are implicitly declared in global scope in each translation unit of a +program. + +\begin{codeblock} +void* operator new(std::size_t); +void* operator new(std::size_t, std::align_val_t); + +void operator delete(void*) noexcept; +void operator delete(void*, std::size_t) noexcept; +void operator delete(void*, std::align_val_t) noexcept; +void operator delete(void*, std::size_t, std::align_val_t) noexcept; + +void* operator new[](std::size_t); +void* operator new[](std::size_t, std::align_val_t); + +void operator delete[](void*) noexcept; +void operator delete[](void*, std::size_t) noexcept; +void operator delete[](void*, std::align_val_t) noexcept; +void operator delete[](void*, std::size_t, std::align_val_t) noexcept; +\end{codeblock} + +These implicit declarations introduce only the function names +\tcode{\keyword{operator} \keyword{new}}, +\tcode{\keyword{operator} \keyword{new}[]}, +\tcode{\keyword{operator} \keyword{delete}}, and +\tcode{\keyword{operator} \keyword{delete}[]}. \begin{note} -Such an $H$ can appear only in a header unit. +The implicit declarations do not introduce +the names \tcode{std}, +\tcode{std::size_t}, +\tcode{std::align_val_t}, +or any other names that the library uses to +declare these names. Thus, a \grammarterm{new-expression}, +\grammarterm{delete-expression}, or function call that refers to one of +these functions without importing or including the header \libheaderref{new} +or importing a \Cpp{} library module\iref{std.modules} +is well-formed. However, referring to \tcode{std} +or \tcode{std::size_t} +or \tcode{std::align_val_t} +is ill-formed unless +a standard library declaration\iref{cstddef.syn,new.syn,std.modules} +of that name precedes\iref{basic.lookup.general} the use of that name. \end{note} +Allocation and/or +deallocation functions may also be declared and defined for any +class\iref{class.free}. \pnum -If two declarations of an entity are -attached to different modules, the program is ill-formed; -no diagnostic is required if neither is reachable from the other. -\begin{example} -\begin{codeblocktu}{\tcode{"decls.h"}} -int f(); // \#1, attached to the global module -int g(); // \#2, attached to the global module -\end{codeblocktu} +If the behavior of an allocation or deallocation function +does not satisfy the semantic constraints +specified in~\ref{basic.stc.dynamic.allocation} +and~\ref{basic.stc.dynamic.deallocation}, +the behavior is undefined. -\begin{codeblocktu}{Module interface of \tcode{M}} -module; -#include "decls.h" -export module M; -export using ::f; // OK, does not declare an entity, exports \#1 -int g(); // error: matches \#2, but attached to \tcode{M} -export int h(); // \#3 -export int k(); // \#4 -\end{codeblocktu} +\indextext{storage duration!dynamic|)} -\begin{codeblocktu}{Other translation unit} -import M; -static int h(); // error: matches \#3 -int k(); // error: matches \#4 -\end{codeblocktu} -\end{example} -As a consequence of these rules, -all declarations of an entity are attached to the same module; -the entity is said to be \defnx{attached}{attached!entity} to that module. +\rSec4[basic.stc.dynamic.allocation]{Allocation functions} \pnum -\indextext{consistency!type declaration}% -\indextext{declaration!multiple}% -For any two declarations of an entity $E$: -\begin{itemize} -\item -If one declares $E$ to be a variable or function, -the other shall declare $E$ as one of the same type. -\item -If one declares $E$ to be an enumerator, the other shall do so. -\item -If one declares $E$ to be a namespace, the other shall do so. -\item -If one declares $E$ to be a type, -the other shall declare $E$ to be a type of the same kind\iref{dcl.type.elab}. -\item -If one declares $E$ to be a class template, -the other shall do so with the same kind and -an equivalent \grammarterm{template-head}\iref{temp.over.link}. -\begin{note} -The declarations can supply different default template arguments. -\end{note} -\item -If one declares $E$ to be a function template or -a (partial specialization of a) variable template, -the other shall declare $E$ to be one -with an equivalent \grammarterm{template-head} and type. -\item -If one declares $E$ to be an alias template, -the other shall declare $E$ to be one with -an equivalent \grammarterm{template-head} and \grammarterm{defining-type-id}. -\item -If one declares $E$ to be a concept, the other shall do so. -\end{itemize} -Types are compared after all adjustments of types (during which -typedefs\iref{dcl.typedef} are replaced by their definitions); -declarations for an array -object can specify array types that differ by the presence or absence of -a major array bound\iref{dcl.array}. -No diagnostic is required if neither declaration is reachable from the other. -\begin{example} -\begin{codeblock} -int f(int x, int x); // error: different entities for \tcode{x} -void g(); // \#1 -void g(int); // OK, different entity from \#1 -int g(); // error: same entity as \#1 with different type -void h(); // \#2 -namespace h {} // error: same entity as \#2, but not a function -\end{codeblock} -\end{example} +\indextext{function!allocation}% +An allocation function that is not a class member function +shall belong to the global scope and not have a name with internal linkage. +The return type shall be \tcode{\keyword{void}*}. The first +parameter shall have type \tcode{std::size_t}\iref{support.types}. The +first parameter shall not have an associated default +argument\iref{dcl.fct.default}. The value of the first parameter +is interpreted as the requested size of the allocation. An allocation +function can be a function template. Such a template shall declare its +return type and first parameter as specified above (that is, template +parameter types shall not be used in the return type and first parameter +type). Allocation function templates shall have two or more parameters. \pnum -\begin{note} -Linkage to non-\Cpp{} declarations can be achieved using a -\grammarterm{linkage-specification}\iref{dcl.link}. -\end{note} -\indextext{linkage|)} +An allocation function attempts to allocate the requested amount of +storage. If it is successful, it returns the address of the start +of a block of storage whose length in bytes is at least as large +as the requested size. +The order, +contiguity, and initial value of storage allocated by successive calls +to an allocation function are unspecified. +Even if the size of the space +requested is zero, the request can fail. If the request succeeds, the +value returned by a replaceable allocation function +is a non-null pointer value\iref{basic.compound} +\tcode{p0} different from any previously returned value \tcode{p1}, +unless that value \tcode{p1} was subsequently passed to a +replaceable deallocation function. +Furthermore, for the library allocation functions +in~\ref{new.delete.single} and~\ref{new.delete.array}, +\tcode{p0} represents the address of a block of storage disjoint from the storage +for any other object accessible to the caller. +The effect of indirecting through a pointer +returned from a request for zero size is undefined. +\begin{footnote} +The intent is +to have \tcode{\keyword{operator} \keyword{new}()} implementable by +calling \tcode{std::malloc()} or \tcode{std::calloc()}, so the rules are +substantially the same. \Cpp{} differs from C in requiring a zero request +to return a non-null pointer. +\end{footnote} \pnum -A declaration $D$ \defnx{names}{name} an entity $E$ if +For an allocation function other than +a reserved placement allocation function\iref{new.delete.placement}, +the pointer returned on a successful call +shall represent the address of storage that is aligned as follows: \begin{itemize} \item -$D$ contains a \grammarterm{lambda-expression} whose closure type is $E$, + If the allocation function takes an argument + of type \tcode{std::align_val_t}, + the storage will have the alignment specified + by the value of this argument. \item -$E$ is not a function or function template and $D$ contains an -\grammarterm{id-expression}, -\grammarterm{type-specifier}, -\grammarterm{nested-name-specifier}, -\grammarterm{template-name}, or -\grammarterm{concept-name} -denoting $E$, or + Otherwise, if the allocation function is named \tcode{\keyword{operator} \keyword{new}[]}, + the storage is aligned for any object that + does not have new-extended alignment\iref{basic.align} and + is no larger than the requested size. \item -$E$ is a function or function template and -$D$ contains an expression that names $E$\iref{basic.def.odr} or -an \grammarterm{id-expression} -that refers to a set of overloads that contains $E$. -\begin{note} -Non-dependent names in an instantiated declaration -do not refer to a set of overloads\iref{temp.res}. -\end{note} + Otherwise, the storage is aligned for any object that + does not have new-extended alignment and is of the requested size. \end{itemize} \pnum -A declaration is an \defn{exposure} -if it either names a TU-local entity (defined below), ignoring -\begin{itemize} -\item -the \grammarterm{function-body} -for a non-inline function or function template -(but not the deduced return type -for a (possibly instantiated) definition of a function -with a declared return type that uses a placeholder type\iref{dcl.spec.auto}), -\item -the \grammarterm{initializer} -for a variable or variable template (but not the variable's type), -\item -friend declarations in a class definition, and -\item -any reference to a non-volatile const object or reference -with internal or no linkage initialized with a constant expression -that is not an odr-use\iref{term.odr.use}, -\end{itemize} -or defines a constexpr variable initialized to a TU-local value (defined below). +An allocation function that fails to allocate storage can invoke the +currently installed new-handler function\iref{new.handler}, if any. \begin{note} -An inline function template can be an exposure even though -certain explicit specializations of it would be usable in other translation units. +\indextext{\idxcode{new_handler}}% +A program-supplied allocation function can obtain the +currently installed \tcode{new_handler} using the +\tcode{std::get_new_handler} function\iref{get.new.handler}. \end{note} +An allocation function that has a non-throwing +exception specification\iref{except.spec} +indicates failure by returning +a null pointer value. +Any other allocation function +never returns a null pointer value and +indicates failure only by throwing an exception\iref{except.throw} of a type +that would match a handler\iref{except.handle} of type +\tcode{std::bad_alloc}\iref{bad.alloc}. \pnum -An entity is \defnx{TU-local}{TU-local!entity} if it is -\begin{itemize} -\item -a type, function, variable, or template that -\begin{itemize} -\item -has a name with internal linkage, or -\item -does not have a name with linkage and is declared, -or introduced by a \grammarterm{lambda-expression}, -within the definition of a TU-local entity, -\end{itemize} -\item -a type with no name that is defined outside a -\grammarterm{class-specifier}, -function body, or -\grammarterm{initializer} -or is introduced by a \grammarterm{defining-type-specifier} -that is used to declare only TU-local entities, -\item -a specialization of a TU-local template, -\item -a specialization of a template with any TU-local template argument, or -\item -a specialization of a template -whose (possibly instantiated) declaration is an exposure. +A global allocation function is only called as the result of a new +expression\iref{expr.new}, or called directly using the function call +syntax\iref{expr.call}, or called indirectly to allocate storage for +a coroutine state\iref{dcl.fct.def.coroutine}, +or called indirectly through calls to the +functions in the \Cpp{} standard library. \begin{note} -A specialization can be produced by implicit or explicit instantiation. +In particular, a +global allocation function is not called to allocate storage for objects +with static storage duration\iref{basic.stc.static}, for objects or references +with thread storage duration\iref{basic.stc.thread}, for objects of +type \tcode{std::type_info}\iref{expr.typeid}, or for an +exception object\iref{except.throw}. \end{note} -\end{itemize} -\pnum -A value or object is \defnx{TU-local}{TU-local!value or object} if either -\begin{itemize} -\item -it is, or is a pointer to, -a TU-local function or the object associated with a TU-local variable, or -\item -it is an object of class or array type and -any of its subobjects or -any of the objects or functions -to which its non-static data members of reference type refer -is TU-local and is usable in constant expressions. -\end{itemize} +\rSec4[basic.stc.dynamic.deallocation]{Deallocation functions} \pnum -If a (possibly instantiated) declaration of, or a deduction guide for, -a non-TU-local entity in a module interface unit -(outside the \grammarterm{private-module-fragment}, if any) or -module partition\iref{module.unit} is an exposure, -the program is ill-formed. -Such a declaration in any other context is deprecated\iref{depr.local}. - -\pnum -If a declaration that appears in one translation unit -names a TU-local entity declared -in another translation unit that is not a header unit, -the program is ill-formed. -A declaration instantiated for a template specialization\iref{temp.spec} -appears at the point of instantiation of the specialization\iref{temp.point}. - -\pnum -\begin{example} -\begin{codeblocktu}{Translation unit \#1} -export module A; -static void f() {} -inline void it() { f(); } // error: is an exposure of \tcode{f} -static inline void its() { f(); } // OK -template void g() { its(); } // OK -template void g<0>(); - -decltype(f) *fp; // error: \tcode{f} (though not its type) is TU-local -auto &fr = f; // OK -constexpr auto &fr2 = fr; // error: is an exposure of \tcode{f} -constexpr static auto fp2 = fr; // OK - -struct S { void (&ref)(); } s{f}; // OK, value is TU-local -constexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-local - -static auto x = []{f();}; // OK -auto x2 = x; // error: the closure type is TU-local -int y = ([]{f();}(),0); // error: the closure type is not TU-local -int y2 = (x,0); // OK - -namespace N { - struct A {}; - void adl(A); - static void adl(int); -} -void adl(double); - -inline void h(auto x) { adl(x); } // OK, but certain specializations are exposures -\end{codeblocktu} -\begin{codeblocktu}{Translation unit \#2} -module A; -void other() { - g<0>(); // OK, specialization is explicitly instantiated - g<1>(); // error: instantiation uses TU-local \tcode{its} - h(N::A{}); // error: overload set contains TU-local \tcode{N::adl(int)} - h(0); // OK, calls \tcode{adl(double)} - adl(N::A{}); // OK; \tcode{N::adl(int)} not found, calls \tcode{N::adl(N::A)} - fr(); // OK, calls \tcode{f} - constexpr auto ptr = fr; // error: \tcode{fr} is not usable in constant expressions here -} -\end{codeblocktu} -\end{example} - -\rSec1[basic.memobj]{Memory and objects} - -\rSec2[intro.memory]{Memory model} - -\pnum -\indextext{memory model|(}% -The fundamental storage unit in the \Cpp{} memory model is the -\defn{byte}. -A byte is at least large enough to contain -the ordinary literal encoding of any element of the basic -\indextext{character set!basic literal}% -literal character set\iref{lex.charset} -and the eight-bit code units of the Unicode -\indextext{UTF-8}% -UTF-8 encoding form -and is composed of a contiguous sequence of -bits, -\begin{footnote} -The number of bits in a byte is reported by the macro -\tcode{CHAR_BIT} in the header \libheaderref{climits}. -\end{footnote} -the number of which is \impldef{bits in a byte}. The least -significant bit is called the \defn{low-order bit}; the most -significant bit is called the \defn{high-order bit}. The memory -available to a \Cpp{} program consists of one or more sequences of -contiguous bytes. Every byte has a unique address. +\indextext{function!deallocation}% +A deallocation function that is not a class member function +shall belong to the global scope and not have a name with internal linkage. \pnum +A deallocation function +is a \defnadj{destroying}{operator delete} +if it has at least two parameters +and its second parameter +is of type \tcode{std::destroying_delete_t}. +A destroying operator delete +shall be a class member function named \tcode{\keyword{operator} \keyword{delete}}. \begin{note} -The representation of types is described -in~\ref{basic.types.general}. +Array deletion cannot use a destroying operator delete. \end{note} \pnum -A \defn{memory location} is either an object of scalar type that is not a bit-field -or a maximal sequence of adjacent bit-fields all having nonzero width. -\begin{note} -Various -features of the language, such as references and virtual functions, might -involve additional memory locations that are not accessible to programs but are -managed by the implementation. -\end{note} -Two or more threads of -execution\iref{intro.multithread} can access separate memory -locations without interfering with each other. +\indextext{\idxcode{delete}!overloading and}% +Each deallocation function shall return \keyword{void}. +If the function is a destroying operator delete +declared in class type \tcode{C}, +the type of its first parameter shall be \tcode{C*}; +otherwise, the type of its first +parameter shall be \tcode{\keyword{void}*}. A deallocation function may have more +than one parameter. +\indextext{deallocation function!usual}% +A \defn{usual deallocation function} is a deallocation function +whose parameters after the first are +\begin{itemize} +\item +optionally, a parameter of type \tcode{std::destroying_delete_t}, then +\item +optionally, a parameter of type \tcode{std::size_t}, +\begin{footnote} +The global \tcode{\keyword{operator} \keyword{delete}(\keyword{void}*, std::size_t)} +precludes use of an +allocation function \tcode{\keyword{void} \keyword{operator} \keyword{new}(std::size_t, std::size_t)} as a placement +allocation function\iref{diff.cpp11.basic}. +\end{footnote} +then +\item +optionally, a parameter of type \tcode{std::align_val_t}. +\end{itemize} +A destroying operator delete shall be a usual deallocation function. +A deallocation function may be an instance of a function +template. Neither the first parameter nor the return type shall depend +on a template parameter. +A deallocation +function template shall have two or more function parameters. A template +instance is never a usual deallocation function, regardless of its +signature. \pnum -\begin{note} -Thus a bit-field and an adjacent non-bit-field are in separate memory -locations, and therefore can be concurrently updated by two threads of execution -without interference. The same applies to two bit-fields, if one is declared -inside a nested struct declaration and the other is not, or if the two are -separated by a zero-length bit-field declaration, or if they are separated by a -non-bit-field declaration. It is not safe to concurrently update two bit-fields -in the same struct if all fields between them are also bit-fields of nonzero -width. -\end{note} +If a deallocation function terminates by throwing an exception, the behavior is undefined. +The value of the first argument supplied to a deallocation function may +be a null pointer value; if so, and if the deallocation function is one +supplied in the standard library, the call has no effect. \pnum -\begin{example} -A class declared as -\begin{codeblock} -struct { - char a; - int b:5, - c:11, - :0, - d:8; - struct {int ee:8;} e; -}; -\end{codeblock} -contains four separate memory locations: The member \tcode{a} and bit-fields -\tcode{d} and \tcode{e.ee} are each separate memory locations, and can be -modified concurrently without interfering with each other. The bit-fields -\tcode{b} and \tcode{c} together constitute the fourth memory location. The -bit-fields \tcode{b} and \tcode{c} cannot be concurrently modified, but -\tcode{b} and \tcode{a}, for example, can be. -\end{example} -\indextext{memory model|)} +If the argument given to a deallocation function in the standard library +is a pointer that is not the null pointer value\iref{basic.compound}, the +deallocation function shall deallocate the storage referenced by the +pointer, ending the duration of the region of storage. -\rSec2[intro.object]{Object model} +\rSec2[class.temporary]{Temporary objects} \pnum -\indextext{object model|(}% -The constructs in a \Cpp{} program create, destroy, refer to, access, and -manipulate objects. -An \defn{object} is created -by a definition\iref{basic.def}, -by a \grammarterm{new-expression}\iref{expr.new}, -by an operation that implicitly creates objects (see below), -when implicitly changing the active member of a union\iref{class.union}, -or -when a temporary object is created\iref{conv.rval,class.temporary}. -An object occupies a region of storage -in its period of construction\iref{class.cdtor}, -throughout its lifetime\iref{basic.life}, -and -in its period of destruction\iref{class.cdtor}. -\begin{note} -A function is not an object, regardless of whether or not it -occupies storage in the way that objects do. -\end{note} -The properties of an -object are determined when the object is created. An object can have a -name\iref{basic.pre}. An object has a storage -duration\iref{basic.stc} which influences its -lifetime\iref{basic.life}. An object has a -type\iref{basic.types}. +\indextext{object temporary|see{temporary}}% +\indextext{temporary}% +\indextext{optimization of temporary|see{temporary, elimination of}}% +\indextext{temporary!elimination of}% +\indextext{temporary!implementation-defined generation of}% +Temporary objects are created +\begin{itemize} +\item +when a prvalue is converted to an xvalue\iref{conv.rval} and +\item +when needed by the implementation to pass or return an object of trivially copyable type (see below). +\end{itemize} +Even when the creation of the temporary object is +unevaluated\iref{expr.context}, +all the semantic restrictions shall be respected as if the temporary object +had been created and later destroyed. \begin{note} -Some objects are -polymorphic\iref{class.virtual}; the implementation -generates information associated with each such object that makes it -possible to determine that object's type during program execution. +This includes accessibility\iref{class.access} and whether it is deleted, +for the constructor selected and for the destructor. However, in the special +case of the operand of a +\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, no temporary is introduced, +so the foregoing does not apply to such a prvalue. \end{note} \pnum -\indextext{subobject}% -Objects can contain other objects, called \defnx{subobjects}{subobject}. -A subobject can be -a \defn{member subobject}\iref{class.mem}, a \defn{base class subobject}\iref{class.derived}, -or an array element. -\indextext{object!complete}% -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} -(which may or may not be within its lifetime), -the created object -is a subobject of \placeholder{e}'s containing object if +The materialization of a temporary object is generally +delayed as long as possible +in order to avoid creating unnecessary temporary objects. +\begin{note} +Temporary objects are materialized: \begin{itemize} \item -the lifetime of \placeholder{e}'s containing object has begun and not ended, and +when binding a reference to a prvalue\iref{dcl.init.ref,expr.type.conv, +expr.dynamic.cast,expr.static.cast,expr.const.cast,expr.cast}, \item -the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and +when performing certain member accesses on a class prvalue\iref{expr.ref,expr.mptr.oper}, \item -the new object is of the same type as \placeholder{e} (ignoring cv-qualification). -\end{itemize} - -\pnum -\indextext{object!providing storage for}% -If a complete object is created\iref{expr.new} -in storage associated with another object \placeholder{e} -of type ``array of $N$ \tcode{\keyword{unsigned} \keyword{char}}'' or -of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, -that array \defn{provides storage} -for the created object if -\begin{itemize} +when invoking an implicit object member function on a class prvalue\iref{expr.call}, \item -the lifetime of \placeholder{e} has begun and not ended, and +when performing an array-to-pointer conversion or subscripting on an array prvalue\iref{conv.array,expr.sub}, \item -the storage for the new object fits entirely within \placeholder{e}, and +when initializing an object of type \tcode{std::initializer_list} from a \grammarterm{braced-init-list}\iref{dcl.init.list}, \item -there is no array object that satisfies these constraints nested within \placeholder{e}. +for certain unevaluated operands\iref{expr.typeid,expr.sizeof}, and +\item +when a prvalue that has type other than \cv{}~\keyword{void} appears as a discarded-value expression\iref{expr.context}. \end{itemize} -\begin{note} -If that portion of the array -previously provided storage for another object, -the lifetime of that object ends -because its storage was reused\iref{basic.life}. \end{note} \begin{example} +Consider the following code: \begin{codeblock} -// assumes that \tcode{sizeof(int)} is equal to 4 - -template -struct AlignedUnion { - alignas(T...) unsigned char data[max(sizeof(T)...)]; +class X { +public: + X(int); + X(const X&); + X& operator=(const X&); + ~X(); }; -int f() { - AlignedUnion au; - int *p = new (au.data) int; // OK, \tcode{au.data} provides storage - char *c = new (au.data) char(); // OK, ends lifetime of \tcode{*p} - char *d = new (au.data + 1) char(); - return *c + *d; // OK -} -struct A { unsigned char a[32]; }; -struct B { unsigned char b[16]; }; -alignas(int) A a; -B *b = new (a.a + 8) B; // \tcode{a.a} provides storage for \tcode{*b} -int *p = new (b->b + 4) int; // \tcode{b->b} provides storage for \tcode{*p} - // \tcode{a.a} does not provide storage for \tcode{*p} (directly), - // but \tcode{*p} is nested within \tcode{a} (see below) +class Y { +public: + Y(int); + Y(Y&&); + ~Y(); +}; + +X f(X); +Y g(Y); + +void h() { + X a(1); + X b = f(X(2)); + Y c = g(Y(3)); + a = f(a); +} \end{codeblock} + +\indextext{class object copy|see{constructor, copy}}% +\indextext{constructor!copy}% +\tcode{X(2)} is constructed in the space used to hold \tcode{f()}'s argument and +\tcode{Y(3)} is constructed in the space used to hold \tcode{g()}'s argument. +Likewise, +\tcode{f()}'s result is constructed directly in \tcode{b} and +\tcode{g()}'s result is constructed directly in \tcode{c}. +On the other hand, the expression +\tcode{a = f(a)} +requires a temporary for +the result of \tcode{f(a)}, +which is materialized so that the reference parameter +of \tcode{X::operator=(const X\&)} can bind to it. \end{example} \pnum -\indextext{object!nested within}% -An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if +When an object of class type \tcode{X} +is passed to or returned from a potentially-evaluated function call, +if \tcode{X} has at least one eligible copy or move constructor\iref{special}, +each such constructor is trivial, +and the destructor of \tcode{X} is either trivial or deleted, +implementations are permitted +to create a temporary object +to hold the function parameter or result object. +The temporary object is constructed +from the function argument or return value, respectively, +and the function's parameter or return object +is initialized as if by +using the eligible trivial constructor to copy the temporary +(even if that constructor is inaccessible +or would not be selected by overload resolution +to perform a copy or move of the object). +\begin{note} +This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. +\end{note} + +\pnum +\indextext{temporary!constructor for}% +\indextext{temporary!destructor for}% +\indextext{temporary!destruction of}% +Temporary objects are destroyed as the last step +in evaluating +the full-expression\iref{intro.execution} +that (lexically) contains the point where +they were created. +This is true even if that evaluation ends in throwing an exception. +The +\indextext{value computation}% +value computations and +\indextext{side effects}% +side effects of destroying a temporary object +are associated only with the full-expression, not with any specific +subexpression. + +\pnum +\indextext{initializer!temporary and declarator}% +\indextext{temporary!order of destruction of}% +There are five contexts in which temporaries are destroyed at a different +point than the end of the full-expression. +The first context is when a default constructor is called to initialize +an element of an array with no corresponding initializer\iref{dcl.init}. +The second context is when a copy constructor is called to copy an element of +an array while the entire array is copied\iref{expr.prim.lambda.capture,class.copy.ctor}. +In either case, if the constructor has one or more default arguments, +the destruction of every temporary created in a default argument is +sequenced before the construction of the next array element, if any. + +\pnum +The third context is when a reference binds to a temporary object. +\begin{footnote} +The same rules apply to initialization of an + \tcode{initializer_list} object\iref{dcl.init.list} with its + underlying temporary array. +\end{footnote} +The temporary object to which the reference is bound or the temporary object +that is the complete object of a subobject to which the reference is bound +persists for the lifetime of the reference if the glvalue +to which the reference is bound +was obtained through one of the following: \begin{itemize} \item -\placeholder{a} is a subobject of \placeholder{b}, or + a temporary materialization conversion\iref{conv.rval}, \item -\placeholder{b} provides storage for \placeholder{a}, or + \tcode{(} \grammarterm{expression} \tcode{)}, + where \grammarterm{expression} is one of these expressions, \item -there exists an object \placeholder{c} -where \placeholder{a} is nested within \placeholder{c}, -and \placeholder{c} is nested within \placeholder{b}. -\end{itemize} - -\pnum -For every object \tcode{x}, there is some object called the -\defn{complete object of} \tcode{x}, determined as follows: -\begin{itemize} + subscripting\iref{expr.sub} of an array operand, + where that operand is one of these expressions, \item -If \tcode{x} is a complete object, then the complete object -of \tcode{x} is itself. - + 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, \item -Otherwise, the complete object of \tcode{x} is the complete object -of the (unique) object that contains \tcode{x}. + a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator + where the left operand is one of these expressions and + the right operand is a pointer to data member of non-reference type, +\item + a + \begin{itemize} + \item \keyword{const_cast}\iref{expr.const.cast}, + \item \keyword{static_cast}\iref{expr.static.cast}, + \item \keyword{dynamic_cast}\iref{expr.dynamic.cast}, or + \item \keyword{reinterpret_cast}\iref{expr.reinterpret.cast} + \end{itemize} + converting, without a user-defined conversion, + a glvalue operand that is one of these expressions + to a glvalue that refers + to the object designated by the operand, or + to its complete object or a subobject thereof, +\item + a conditional expression\iref{expr.cond} that is a glvalue + where the second or third operand is one of these expressions, or +\item + a comma expression\iref{expr.comma} that is a glvalue + where the right operand is one of these expressions. \end{itemize} +\begin{example} +\begin{codeblock} +template using id = T; -\pnum -If a complete object, a member subobject, or an array element is of -class type, its type is considered the \defn{most derived -class}, to distinguish it from the class type of any base class subobject; -an object of a most derived class type or of a non-class type is called a -\defn{most derived object}. +int i = 1; +int&& a = id{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} +const int& b = static_cast(0); // temporary \tcode{int} has same lifetime as \tcode{b} +int&& c = cond ? id{1, 2, 3}[i] : static_cast(0); + // exactly one of the two temporaries is lifetime-extended +\end{codeblock} +\end{example} +\begin{note} +An explicit type conversion\iref{expr.type.conv,expr.cast} +is interpreted as +a sequence of elementary casts, +covered above. +\begin{example} +\begin{codeblock} +const int& x = (const int&)1; // temporary for value 1 has same lifetime as x +\end{codeblock} +\end{example} +\end{note} +\begin{note} +If a temporary object has a reference member initialized by another temporary object, +lifetime extension applies recursively to such a member's initializer. +\begin{example} +\begin{codeblock} +struct S { + const int& m; +}; +const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} +\end{codeblock} +\end{example} +\end{note} -\pnum -A \defn{potentially-overlapping subobject} is either: +The exceptions to this lifetime rule are: \begin{itemize} -\item a base class subobject, or -\item a non-static data member -declared with the \tcode{no_unique_address} attribute\iref{dcl.attr.nouniqueaddr}. -\end{itemize} +\item A temporary object bound to a reference parameter in a function call\iref{expr.call} +persists until the completion of the full-expression containing the call. -\pnum -\indextext{object!zero size}% -\indextext{object!nonzero size}% -An object has nonzero size if it -\begin{itemize} -\item is not a potentially-overlapping subobject, or -\item is not of class type, or -\item is of a class type with virtual member functions or virtual base classes, or -\item has subobjects of nonzero size or unnamed bit-fields of nonzero length. +\item A temporary object bound to a reference element of +an aggregate of class type initialized from +a parenthesized \grammarterm{expression-list}\iref{dcl.init} +persists until the completion of the full-expression +containing the \grammarterm{expression-list}. + +\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. +\begin{note} +This might introduce a dangling reference. +\end{note} +\begin{example} +\begin{codeblock} +struct S { int mi; const std::pair& mp; }; +S a { 1, {2,3} }; +S* p = new S{ 1, {2,3} }; // creates dangling reference +\end{codeblock} +\end{example} \end{itemize} -Otherwise, if the object is a base class subobject -of a standard-layout class type -with no non-static data members, -it has zero size. -Otherwise, the circumstances under which the object has zero size -are \impldef{which non-standard-layout objects -containing no data are considered empty}. -\indextext{most derived object!bit-field}% -Unless it is a bit-field\iref{class.bit}, -an object with nonzero size -shall occupy one or more bytes of storage, -including every byte that is occupied in full or in part -by any of its subobjects. -An object of trivially copyable or -standard-layout type\iref{basic.types.general} shall occupy contiguous bytes of -storage. \pnum -An object is a \defnadj{potentially non-unique}{object} if it is -a string literal object\iref{lex.string}, -the backing array of an initializer list\iref{dcl.init.ref}, or -a subobject thereof. +The fourth context is when a temporary object +is created in the \grammarterm{for-range-initializer} of a range-based \keyword{for} statement. +If such a temporary object would otherwise be destroyed +at the end of the \grammarterm{for-range-initializer} full-expression, +the object persists for the lifetime of the reference +initialized by the \grammarterm{for-range-initializer}. + +\pnum +The fifth context is when a temporary object +is created in a structured binding declaration\iref{dcl.struct.bind}. +Any temporary objects introduced by +the \grammarterm{initializer}{s} for the variables +with unique names +are destroyed at the end of the structured binding declaration. + +\pnum +Let \tcode{x} and \tcode{y} each be either +a temporary object whose lifetime is not extended, or +a function parameter. +If the lifetimes of \tcode{x} and \tcode{y} end at +the end of the same full-expression, and +\tcode{x} is initialized before \tcode{y}, then +the destruction of \tcode{y} is sequenced before that of \tcode{x}. +If the lifetime of two or more temporaries +with lifetimes extending beyond the full-expressions in which they were created +ends at the same point, +these temporaries are destroyed at that point in the reverse order of the +completion of their construction. +In addition, the destruction of such temporaries shall +take into account the ordering of destruction of objects with static, thread, or +automatic storage duration\iref{basic.stc.static,basic.stc.thread,basic.stc.auto}; +that is, if +\tcode{obj1} +is an object with the same storage duration as the temporary and +created before the temporary is created +the temporary shall be destroyed before +\tcode{obj1} +is destroyed; +if +\tcode{obj2} +is an object with the same storage duration as the temporary and +created after the temporary is created +the temporary shall be destroyed after +\tcode{obj2} +is destroyed. \pnum -\indextext{most derived object!bit-field}% -\indextext{most derived object!zero size subobject}% -Unless an object is a bit-field or a subobject of zero size, the -address of that object is the address of the first byte it occupies. -Two objects -with overlapping lifetimes -that are not bit-fields -may have the same address if -\begin{itemize} -\item one is nested within the other, -\item at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, -or -\item they are both potentially non-unique objects; -\end{itemize} -otherwise, they have distinct addresses -and occupy disjoint bytes of storage. -\begin{footnote} -Under the ``as-if'' rule an -implementation is allowed to store two objects at the same machine address or -not store an object at all if the program cannot observe the -difference\iref{intro.execution}. -\end{footnote} \begin{example} \begin{codeblock} -static const char test1 = 'x'; -static const char test2 = 'x'; -const bool b = &test1 != &test2; // always \tcode{true} - -static const char (&r) [] = "x"; -static const char *s = "x"; -static std::initializer_list il = { 'x' }; -const bool b2 = r != il.begin(); // unspecified result -const bool b3 = r != s; // unspecified result -const bool b4 = il.begin() != &test1; // always \tcode{true} -const bool b5 = r != &test1; // always \tcode{true} +struct S { + S(); + S(int); + friend S operator+(const S&, const S&); + ~S(); +}; +S obj1; +const S& cr = S(16)+S(23); +S obj2; \end{codeblock} + +The expression +\tcode{S(16) + S(23)} +creates three temporaries: +a first temporary +\tcode{T1} +to hold the result of the expression +\tcode{S(16)}, +a second temporary +\tcode{T2} +to hold the result of the expression +\tcode{S(23)}, +and a third temporary +\tcode{T3} +to hold the result of the addition of these two expressions. +The temporary +\tcode{T3} +is then bound to the reference +\tcode{cr}. +It is unspecified whether +\tcode{T1} +or +\tcode{T2} +is created first. +On an implementation where +\tcode{T1} +is created before +\tcode{T2}, +\tcode{T2} +shall be destroyed before +\tcode{T1}. +The temporaries +\tcode{T1} +and +\tcode{T2} +are bound to the reference parameters of +\tcode{\keyword{operator}+}; +these temporaries are destroyed at the end of the full-expression +containing the call to +\tcode{\keyword{operator}+}. +The temporary +\tcode{T3} +bound to the reference +\tcode{cr} +is destroyed at the end of +\tcode{cr}'s +lifetime, that is, at the end of the program. +In addition, the order in which +\tcode{T3} +is destroyed takes into account the destruction order of other objects with +static storage duration. +That is, because +\tcode{obj1} +is constructed before +\tcode{T3}, +and +\tcode{T3} +is constructed before +\tcode{obj2}, +\tcode{obj2} +shall be destroyed before +\tcode{T3}, +and +\tcode{T3} +shall be destroyed before +\tcode{obj1}. \end{example} -The address of a non-bit-field subobject of zero size is -the address of an unspecified byte of storage -occupied by the complete object of that subobject. + +\rSec1[basic.types]{Types}% + +\rSec2[basic.types.general]{General}% +\indextext{type|(} \pnum -Some operations are described as -\defnx{implicitly creating objects}{object!implicit creation} -within a specified region of storage. -For each operation that is specified as implicitly creating objects, -that operation implicitly creates and starts the lifetime of -zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type} -in its specified region of storage -if doing so would result in the program having defined behavior. -If no such set of objects would give the program defined behavior, -the behavior of the program is undefined. -If multiple such sets of objects would give the program defined behavior, -it is unspecified which such set of objects is created. \begin{note} -Such operations do not start the lifetimes of subobjects of such objects -that are not themselves of implicit-lifetime types. +\ref{basic.types} and the subclauses thereof +impose requirements on implementations regarding the representation +of types. +There are two kinds of types: fundamental types and compound types. +Types describe objects\iref{intro.object}, +references\iref{dcl.ref}, +or functions\iref{dcl.fct}. \end{note} \pnum -Further, after implicitly creating objects within a specified region of storage, -some operations are described as producing a pointer to a -\defnadj{suitable created}{object}. -These operations select one of the implicitly-created objects -whose address is the address of the start of the region of storage, -and produce a pointer value that points to that object, -if that value would result in the program having defined behavior. -If no such pointer value would give the program defined behavior, -the behavior of the program is undefined. -If multiple such pointer values would give the program defined behavior, -it is unspecified which such pointer value is produced. +\indextext{object!byte copying and|(}% +\indextext{type!trivially copyable}% +For any object (other than a potentially-overlapping subobject) of trivially copyable type +\tcode{T}, whether or not the object holds a valid value of type +\tcode{T}, the underlying bytes\iref{intro.memory} making up the +object can be copied into an array of +\keyword{char}, +\tcode{\keyword{unsigned} \keyword{char}}, or +\tcode{std::byte}\iref{cstddef.syn}. +\begin{footnote} +By using, for example, the library +functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. +\end{footnote} +If the content of that array +is copied back into the object, the object shall +subsequently hold its original value. +\begin{example} +\begin{codeblock} +constexpr std::size_t N = sizeof(T); +char buf[N]; +T obj; // \tcode{obj} initialized to its original value +std::memcpy(buf, &obj, N); // between these two calls to \tcode{std::memcpy}, \tcode{obj} might be modified +std::memcpy(&obj, buf, N); // at this point, each subobject of \tcode{obj} of scalar type holds its original value +\end{codeblock} +\end{example} \pnum +For two distinct objects \tcode{obj1} and \tcode{obj2} +of trivially copyable type \tcode{T}, +where neither \tcode{obj1} nor \tcode{obj2} is a potentially-overlapping subobject, +if the underlying bytes\iref{intro.memory} making up +\tcode{obj1} are copied into \tcode{obj2}, +\begin{footnote} +By using, for example, +the library functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. +\end{footnote} + \tcode{obj2} shall subsequently hold the same value as +\tcode{obj1}. \begin{example} \begin{codeblock} -#include -struct X { int a, b; }; -X *make_x() { - // The call to \tcode{std::malloc} implicitly creates an object of type \tcode{X} - // and its subobjects \tcode{a} and \tcode{b}, and returns a pointer to that \tcode{X} object - // (or an object that is pointer-interconvertible\iref{basic.compound} with it), - // in order to give the subsequent class member access operations - // defined behavior. - X *p = (X*)std::malloc(sizeof(struct X)); - p->a = 1; - p->b = 2; - return p; -} +T* t1p; +T* t2p; + // provided that \tcode{t2p} points to an initialized object ... +std::memcpy(t1p, t2p, sizeof(T)); + // at this point, every subobject of trivially copyable type in \tcode{*t1p} contains + // the same value as the corresponding subobject in \tcode{*t2p} \end{codeblock} \end{example} +\indextext{object!byte copying and|)} \pnum -Except during constant evaluation, -an operation that begins the lifetime of -an array of \tcode{unsigned char} or \tcode{std::byte} -implicitly creates objects within the region of storage occupied by the array. -\begin{note} -The array object provides storage for these objects. -\end{note} -Except during constant evaluation, -any implicit or explicit invocation of a function -named \tcode{\keyword{operator} \keyword{new}} or \tcode{\keyword{operator} \keyword{new}[]} -implicitly creates objects in the returned region of storage and -returns a pointer to a suitable created object. -\begin{note} -Some functions in the \Cpp{} standard library implicitly create objects% -\iref{obj.lifetime,c.malloc,mem.res.public,bit.cast,cstring.syn}. -\end{note} -\indextext{object model|)} - -\rSec2[basic.life]{Lifetime} +\label{term.object.representation}% +The \defnx{object representation}{representation!object} +of a complete object type \tcode{T} is the +sequence of \placeholder{N} \tcode{\keyword{unsigned} \keyword{char}} objects taken up +by a non-bit-field complete object of type \tcode{T}, +where \placeholder{N} equals +\tcode{\keyword{sizeof}(T)}. +The \defnx{value representation}{representation!value} +of a type \tcode{T} is the set of bits +in the object representation of \tcode{T} +that participate in representing a value of type \tcode{T}. +The object and value representation of +a non-bit-field complete object of type \tcode{T} are +the bytes and bits, respectively, of +the object corresponding to the object and value representation of its type. +The object representation of a bit-field object is +the sequence of \placeholder{N} bits taken up by the object, +where \placeholder{N} is the width of the bit-field\iref{class.bit}. +The value representation of a bit-field object is +the set of bits in the object representation that +participate in representing its value. +\label{term.padding.bits}% +Bits in the object representation of a type or object that are +not part of the value representation +are \defn{padding bits}. +For trivially copyable types, the value representation is +a set of bits in the object representation that determines a +\defn{value}, which is one discrete element of an +\impldef{values of a trivially copyable type} set of values. +\begin{footnote} +The intent is that the memory model of \Cpp{} is compatible +with that of the C programming language. +\end{footnote} \pnum -\indextext{object lifetime|(}% -The \defn{lifetime} of an object or reference is a runtime property of the -object or reference. -A variable is said to have \defnadj{vacuous}{initialization} -if it is default-initialized, no other initialization is performed, and, -if it is of class type or a (possibly multidimensional) array thereof, -a trivial constructor of that class type is selected for -the default-initialization. -The lifetime of an object of type \tcode{T} begins when: -\begin{itemize} -\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}, -\end{itemize} -except that if the object is a union member or subobject thereof, -its lifetime only begins if that union member is the -initialized member in the union\iref{dcl.init.aggr,class.base.init}, -or as described in -\ref{class.union}, \ref{class.copy.ctor}, and \ref{class.copy.assign}, -and except as described in \ref{allocator.members}. -The lifetime of an object \placeholder{o} of type \tcode{T} ends when: -\begin{itemize} -\item if \tcode{T} is a non-class type, the object is destroyed, or -\item if \tcode{T} is a class type, the destructor call starts, or -\item the storage which the object occupies is released, -or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. -\end{itemize} -When evaluating a \grammarterm{new-expression}, -storage is considered reused after it is returned from the allocation function, -but before the evaluation of the \grammarterm{new-initializer}\iref{expr.new}. +\indextext{type!incompletely-defined object}% +A class that has been declared but not defined, an enumeration type in certain +contexts\iref{dcl.enum}, or an array of unknown +bound or of incomplete element type, is an +\defnadj{incompletely-defined}{object type}. +\begin{footnote} +The size and layout of an instance of an incompletely-defined +object type is unknown. +\end{footnote} +\label{term.incomplete.type}% +Incompletely-defined object types and \cv{}~\keyword{void} are +\defnadjx{incomplete}{types}{type}\iref{basic.fundamental}. +\begin{note} +Objects cannot be defined to have an incomplete type\iref{basic.def}. +\end{note} + +\pnum +A class type (such as ``\tcode{\keyword{class} X}'') can be incomplete at one +point in a translation unit and complete later on; the type +``\tcode{\keyword{class} X}'' is the same type at both points. The declared type +of an array object can be an array of incomplete class type and +therefore incomplete; if the class type is completed later on in the +translation unit, the array type becomes complete; the array type at +those two points is the same type. The declared type of an array object +can be an array of unknown bound and therefore be incomplete at one +point in a translation unit and complete later on; the array types at +those two points (``array of unknown bound of \tcode{T}'' and ``array of +\tcode{N} \tcode{T}'') are different types. +\begin{note} +The type of a pointer or reference to array of unknown bound +permanently points to or refers to an incomplete type. +An array of unknown bound named by a \keyword{typedef} declaration +permanently refers to an incomplete type. +In either case, the array type cannot be completed. +\end{note} \begin{example} +\indextext{type!example of incomplete}% \begin{codeblock} -struct S { - int m; -}; +class X; // \tcode{X} is an incomplete type +extern X* xp; // \tcode{xp} is a pointer to an incomplete type +extern int arr[]; // the type of arr is incomplete +typedef int UNKA[]; // \tcode{UNKA} is an incomplete type +UNKA* arrp; // \tcode{arrp} is a pointer to an incomplete type +UNKA** arrpp; -void f() { - S x{1}; - new(&x) S(x.m); // undefined behavior +void foo() { + xp++; // error: \tcode{X} is incomplete + arrp++; // error: incomplete type + arrpp++; // OK, sizeof \tcode{UNKA*} is known +} + +struct X { int i; }; // now \tcode{X} is a complete type +int arr[10]; // now the type of \tcode{arr} is complete + +X x; +void bar() { + xp = &x; // OK; type is ``pointer to \tcode{X}'' + arrp = &arr; // OK; qualification conversion\iref{conv.qual} + xp++; // OK, \tcode{X} is complete + arrp++; // error: \tcode{UNKA} can't be completed } \end{codeblock} \end{example} -\pnum -\indextext{reference lifetime}% -The lifetime of a reference begins when its initialization is complete. -The lifetime of a reference ends as if it were a scalar object requiring storage. - \pnum \begin{note} -\ref{class.base.init} -describes the lifetime of base and member subobjects. +The rules for declarations and expressions describe in which +contexts incomplete types are prohibited. \end{note} \pnum -The properties ascribed to objects and references throughout this document -apply for a given object or reference only during its lifetime. -\begin{note} -In particular, before the lifetime of an object starts and after its -lifetime ends there are significant restrictions on the use of the -object, as described below, in~\ref{class.base.init}, and -in~\ref{class.cdtor}. Also, the behavior of an object under construction -and destruction can differ from the behavior of an object whose -lifetime has started and not ended. \ref{class.base.init} -and~\ref{class.cdtor} describe the behavior of an object during its periods -of construction and destruction. -\end{note} +\label{term.object.type}% +An \defn{object type} is a (possibly cv-qualified) type that is not +a function type, not a reference type, and not \cv{}~\keyword{void}. \pnum -A program may end the lifetime of an object of class type without invoking the -destructor, by reusing or releasing the storage as described above. -\begin{note} -A \grammarterm{delete-expression}\iref{expr.delete} invokes the destructor -prior to releasing the storage. -\end{note} -In this case, the destructor is not implicitly invoked. +\indextext{class!trivial}% +\indextext{class!trivially copyable}% +\indextext{class!standard-layout}% +\label{term.scalar.type}% +Arithmetic types\iref{basic.fundamental}, enumeration types, +pointer types, pointer-to-member types\iref{basic.compound}, +\tcode{std::nullptr_t}, +and +cv-qualified\iref{basic.type.qualifier} versions of these +types are collectively called +\defnadjx{scalar}{types}{type}. +\label{term.trivially.copyable.type}% +Scalar types, trivially copyable class types\iref{class.prop}, +arrays of such types, and cv-qualified versions of these +types are collectively called \defnadjx{trivially copyable}{types}{type}. +\label{term.trivial.type}% +Scalar types, trivial class types\iref{class.prop}, +arrays of such types, and cv-qualified versions of these +types are collectively called +\defnadjx{trivial}{types}{type}. +\label{term.standard.layout.type}% +Scalar types, standard-layout class +types\iref{class.prop}, arrays of such types, and +cv-qualified versions of these types +are collectively called \defnadjx{standard-layout}{types}{type}. +\label{term.implicit.lifetime.type}% +Scalar types, implicit-lifetime class types\iref{class.prop}, +array types, and cv-qualified versions of these types +are collectively called \defnadjx{implicit-lifetime}{types}{type}. + +\pnum +\label{term.literal.type}% +A type is a \defnadj{literal}{type} if it is: +\begin{itemize} +\item \cv{}~\keyword{void}; or +\item a scalar type; or +\item a reference type; or +\item an array of literal type; or +\item a possibly cv-qualified class type\iref{class} that +has all of the following properties: +\begin{itemize} +\item it has a constexpr destructor\iref{dcl.constexpr}, +\item all of its non-static non-variant data members and base classes are of non-volatile literal types, and +\item it +\begin{itemize} +\item is a closure type\iref{expr.prim.lambda.closure}, +\item is an aggregate union type that has either +no variant members or +at least one variant member of non-volatile literal type, +\item is a non-union aggregate type for which +each of its anonymous union members +satisfies the above requirements for an aggregate union type, or +\item has at least one constexpr constructor or constructor template +(possibly inherited\iref{namespace.udecl} from a base class) +that is not a copy or move constructor. +\end{itemize} +\end{itemize} +\end{itemize} \begin{note} -The correct behavior of a program often depends on -the destructor being invoked for each object of class type. +A literal type is one for which +it might be possible to create an object +within a constant expression. +It is not a guarantee that it is possible to create such an object, +nor is it a guarantee that any object of that type +will be usable in a constant expression. \end{note} \pnum -Before the lifetime of an object has started but after the storage which -the object will occupy has been allocated -\begin{footnote} -For example, before the dynamic initialization of -an object with static storage duration\iref{basic.start.dynamic}. +\label{term.layout.compatible.type}% +Two types \cvqual{cv1} \tcode{T1} and \cvqual{cv2} \tcode{T2} are +\defnadjx{layout-compatible}{types}{type} +if \tcode{T1} and \tcode{T2} are the same type, +layout-compatible enumerations\iref{dcl.enum}, or +layout-compatible standard-layout class types\iref{class.mem}. +\rSec2[basic.type.qualifier]{CV-qualifiers} + +\pnum +\indextext{cv-qualifier}% +\indextext{\idxcode{const}}% +\indextext{\idxcode{volatile}}% +Each type other than a function or reference type +is part of a group of four distinct, but related, types: +a \defn{cv-unqualified} version, +a \defn{const-qualified} version, +a \defn{volatile-qualified} version, and +a \defn{const-volatile-qualified} version. +The types in each such group shall have +the same representation and alignment requirements\iref{basic.align}. +\begin{footnote} +The same representation and alignment requirements +are meant to imply interchangeability as +arguments to functions, +return values from functions, and +non-static data members of unions. \end{footnote} -or, after the lifetime of an object has ended and before the storage -which the object occupied is reused or released, any pointer that represents the address of -the storage location where the object will be or was located may be -used but only in limited ways. -For an object under construction or destruction, see~\ref{class.cdtor}. -Otherwise, such -a pointer refers to allocated -storage\iref{basic.stc.dynamic.allocation}, and using the pointer as -if the pointer were of type \tcode{\keyword{void}*} is -well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in -limited ways, as described below. The -program has undefined behavior if +A function or reference type is always cv-unqualified. \begin{itemize} -\item - the pointer is used as the operand of a \grammarterm{delete-expression}, -\item - the pointer is used to access a non-static data member or call a - non-static member function of the object, or -\item - the pointer is implicitly converted\iref{conv.ptr} to a pointer - to a virtual base class, or -\item - the pointer is used as the operand of a - \keyword{static_cast}\iref{expr.static.cast}, except when the conversion - is to pointer to \cv{}~\keyword{void}, or to pointer to \cv{}~\keyword{void} - and subsequently to pointer to - \cv{}~\keyword{char}, - \cv{}~\tcode{\keyword{unsigned} \keyword{char}}, or - \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or -\item - the pointer is used as the operand of a - \keyword{dynamic_cast}\iref{expr.dynamic.cast}. -\end{itemize} -\begin{example} -\begin{codeblock} -#include - -struct B { - virtual void f(); - void mutate(); - virtual ~B(); -}; - -struct D1 : B { void f(); }; -struct D2 : B { void f(); }; - -void B::mutate() { - new (this) D2; // reuses storage --- ends the lifetime of \tcode{*this} - f(); // undefined behavior - ... = this; // OK, \keyword{this} points to valid memory -} +\item A \defnadj{const}{object} is an object of type \tcode{\keyword{const} T} or a + non-mutable subobject of a const object. -void g() { - void* p = std::malloc(sizeof(D1) + sizeof(D2)); - B* pb = new (p) D1; - pb->mutate(); - *pb; // OK, \tcode{pb} points to valid memory - void* q = pb; // OK, \tcode{pb} points to valid memory - pb->f(); // undefined behavior: lifetime of \tcode{*pb} has ended -} -\end{codeblock} -\end{example} +\item A \defnadj{volatile}{object} is an object of type + \tcode{\keyword{volatile} T} or a subobject of a volatile object. -\pnum -Similarly, before the lifetime of an object has started but after the -storage which the object will occupy has been allocated or, after the -lifetime of an object has ended and before the storage which the object -occupied is reused or released, any glvalue that refers to the original -object may be used but only in limited ways. -For an object under construction or destruction, see~\ref{class.cdtor}. -Otherwise, such -a glvalue refers to -allocated storage\iref{basic.stc.dynamic.allocation}, and using the -properties of the glvalue that do not depend on its value is -well-defined. The program has undefined behavior if -\begin{itemize} -\item the glvalue is used to access the object, or -\item the glvalue is used to call a non-static member function of the object, or -\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or -\item the glvalue is used as the operand of a -\keyword{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of -\keyword{typeid}. +\item A \defnadj{const volatile}{object} is an object of type + \tcode{\keyword{const} \keyword{volatile} T}, a non-mutable subobject of a const volatile object, + a const subobject of a volatile object, or a non-mutable volatile + subobject of a const object. \end{itemize} +\begin{note} +The type of an object\iref{intro.object} includes +the \grammarterm{cv-qualifier}s specified in the +\grammarterm{decl-specifier-seq}\iref{dcl.spec}, +\grammarterm{declarator}\iref{dcl.decl}, +\grammarterm{type-id}\iref{dcl.name}, or +\grammarterm{new-type-id}\iref{expr.new} +when the object is created. +\end{note} \pnum -An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if -\begin{itemize} -\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 - -\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$. -\end{itemize} +Except for array types, a compound type\iref{basic.compound} is not cv-qualified by the +cv-qualifiers (if any) of the types from which it is compounded. \pnum -After the lifetime of an object has ended and before the storage which the -object occupied is reused or released, if a new object is created at the -storage location which the original object occupied and the original object was -transparently replaceable by the new object, a pointer that pointed to the -original object, a reference that referred to the original object, or the name -of the original object will automatically refer to the new object and, once the -lifetime of the new object has started, can be used to manipulate the new -object. - +\indextext{array!\idxcode{const}}% +An array type whose elements are cv-qualified +is also considered to have the same cv-qualifications +as its elements. +\begin{note} +Cv-qualifiers applied to an array +type attach to the underlying element type, so the notation +``\cv{}~\tcode{T}'', where \tcode{T} is an array type, refers to +an array whose elements are so-qualified\iref{dcl.array}. +\end{note} \begin{example} \begin{codeblock} -struct C { - int i; - void f(); - const C& operator=( const C& ); -}; - -const C& C::operator=( const C& other) { - if ( this != &other ) { - this->~C(); // lifetime of \tcode{*this} ends - new (this) C(other); // new object of type \tcode{C} created - f(); // well-defined - } - return *this; -} - -C c1; -C c2; -c1 = c2; // well-defined -c1.f(); // well-defined; \tcode{c1} refers to a new object of type \tcode{C} +typedef char CA[5]; +typedef const char CC; +CC arr1[5] = { 0 }; +const CA arr2 = { 0 }; \end{codeblock} +The type of both \tcode{arr1} and \tcode{arr2} is ``array of 5 +\tcode{\keyword{const} \keyword{char}}'', and the array type is considered to be +const-qualified. \end{example} +\indextext{type|)} + +\pnum \begin{note} -If these conditions are not met, -a pointer to the new object can be obtained from -a pointer that represents the address of its storage -by calling \tcode{std::launder}\iref{ptr.launder}. +See~\ref{dcl.fct} and~\ref{over.match.funcs} regarding function +types that have \grammarterm{cv-qualifier}{s}. \end{note} \pnum -If a program ends the lifetime of an object of type \tcode{T} with -static\iref{basic.stc.static}, thread\iref{basic.stc.thread}, -or automatic\iref{basic.stc.auto} -storage duration and if \tcode{T} has a non-trivial destructor, -\begin{footnote} -That -is, an object for which a destructor will be called -implicitly---upon exit from the block for an object with -automatic storage duration, upon exit from the thread for an object with -thread storage duration, or upon exit from the program for an object -with static storage duration. -\end{footnote} -and another object of the original type does not occupy -that same storage location when the implicit destructor call takes -place, the behavior of the program is undefined. This is true -even if the block is exited with an exception. -\begin{example} -\begin{codeblock} -class T { }; -struct B { - ~B(); -}; +There is a partial ordering on cv-qualifiers, so that a type can be +said to be \defn{more cv-qualified} than another. +\tref{basic.type.qualifier.rel} shows the relations that +constitute this ordering. -void h() { - B b; - new (&b) T; -} // undefined behavior at block exit -\end{codeblock} -\end{example} +\begin{floattable}{Relations on \keyword{const} and \keyword{volatile}}{basic.type.qualifier.rel} +{ccc} +\topline +\cvqual{no cv-qualifier} &<& \keyword{const} \\ +\cvqual{no cv-qualifier} &<& \keyword{volatile} \\ +\cvqual{no cv-qualifier} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\keyword{const} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\keyword{volatile} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\end{floattable} \pnum -Creating a new object within the storage that a const, complete -object with static, thread, or automatic storage duration occupies, -or within the storage that such a const object used to occupy before -its lifetime ended, results in undefined behavior. +In this document, the notation \cv{} (or +\cvqual{cv1}, \cvqual{cv2}, etc.), used in the description of types, +represents an arbitrary set of cv-qualifiers, i.e., one of +\{\keyword{const}\}, \{\keyword{volatile}\}, \{\keyword{const}, +\keyword{volatile}\}, or the empty set. +For a type \cv{}~\tcode{T}, the \defnx{top-level cv-qualifiers}{cv-qualifier!top-level} +of that type are those denoted by \cv. \begin{example} -\begin{codeblock} -struct B { - B(); - ~B(); -}; - -const B b; - -void h() { - b.~B(); - new (const_cast(&b)) const B; // undefined behavior -} -\end{codeblock} +The type corresponding to the \grammarterm{type-id} +\tcode{\keyword{const} \keyword{int}\&} +has no top-level cv-qualifiers. +The type corresponding to the \grammarterm{type-id} +\tcode{\keyword{volatile} \keyword{int} * \keyword{const}} +has the top-level cv-qualifier \keyword{const}. +For a class type \tcode{C}, +the type corresponding to the \grammarterm{type-id} +\tcode{\keyword{void} (C::* \keyword{volatile})(\keyword{int}) \keyword{const}} +has the top-level cv-qualifier \keyword{volatile}. \end{example} -\pnum -In this subclause, ``before'' and ``after'' refer to the ``happens before'' -relation\iref{intro.multithread}. -\begin{note} -Therefore, undefined behavior results -if an object that is being constructed in one thread is referenced from another -thread without adequate synchronization. -\end{note} -\indextext{object lifetime|)} +\rSec2[basic.fundamental]{Fundamental types} -\rSec2[basic.indet]{Indeterminate and erroneous values} +\pnum +\indextext{type!implementation-defined \tcode{sizeof}}% +There are five \defnadjx{standard signed integer}{types}{type}: +\indextext{type!\idxcode{signed char}}% +\indextext{type!\idxcode{short}}% +\indextext{type!\idxcode{int}}% +\indextext{type!\idxcode{long}}% +\indextext{type!\idxcode{long long}}% +``\tcode{\keyword{signed} \keyword{char}}'', ``\tcode{\keyword{short} \keyword{int}}'', ``\keyword{int}'', +``\tcode{\keyword{long} \keyword{int}}'', and ``\tcode{\keyword{long} \keyword{long} \keyword{int}}''. In +this list, each type provides at least as much storage as those +preceding it in the list. +There may also be \impldef{extended signed integer types} +\defnadjx{extended signed integer}{types}{type}. +The standard and extended signed integer types are collectively called +\defnadjx{signed integer}{types}{type}. +The range of representable values for a signed integer type is +$-2^{N-1}$ to $2^{N-1}-1$ (inclusive), +where \placeholder{N} is called the \defn{width} of the type. +\indextext{integral type!implementation-defined \tcode{sizeof}}% +\begin{note} +Plain \tcode{int}s are intended to have +the natural width suggested by the architecture of the execution environment; +the other signed integer types are provided to meet special needs. +\end{note} \pnum -When storage for an object with automatic or dynamic storage duration -is obtained, -the bytes comprising the storage for the object -have the following initial value: -\begin{itemize} -\item -If the object has dynamic storage duration, or -is the object associated with a variable or function parameter -whose first declaration is marked with -the \tcode{[[indeterminate]]} attribute\iref{dcl.attr.indet}, -the bytes have \defnadjx{indeterminate}{values}{value}; -\item -otherwise, the bytes have \defnadjx{erroneous}{values}{value}, -where each value is determined by the implementation -independently of the state of the program. -\end{itemize} -If no initialization is performed for an object (including subobjects), -such a byte retains its initial value -until that value is replaced\iref{dcl.init.general,expr.ass}. -If any bit in the value representation has an indeterminate value, -the object has an indeterminate value; -otherwise, if any bit in the value representation has an erroneous value, -the object has an erroneous value\iref{conv.lval}. +\indextext{type!\idxcode{unsigned}}% +For each of the standard signed integer types, +there exists a corresponding (but different) +\defnadj{standard unsigned integer}{type}: +\indextext{type!\idxcode{unsigned char}}% +\indextext{type!\idxcode{unsigned short}}% +\indextext{type!\idxcode{unsigned int}}% +\indextext{type!\idxcode{unsigned long}}% +\indextext{type!\idxcode{unsigned long long}}% +``\tcode{\keyword{unsigned} \keyword{char}}'', ``\tcode{\keyword{unsigned} \keyword{short} \keyword{int}}'', +``\tcode{\keyword{unsigned} \keyword{int}}'', ``\tcode{\keyword{unsigned} \keyword{long} \keyword{int}}'', and +``\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}''. +Likewise, for each of the extended signed integer types, +there exists a corresponding \defnadj{extended unsigned integer}{type}. +The standard and extended unsigned integer types +are collectively called \defnadjx{unsigned integer}{types}{type}. +An unsigned integer type has the same width \placeholder{N} +as the corresponding signed integer type. +\indextext{arithmetic!\idxcode{unsigned}}% +The range of representable values for the unsigned type is +$0$ to $2^N-1$ (inclusive); +arithmetic for the unsigned type is performed modulo $2^N$. \begin{note} -Objects with static or thread storage duration are zero-initialized, -see~\ref{basic.start.static}. +Unsigned arithmetic does not overflow. +Overflow for signed arithmetic yields undefined behavior\iref{expr.pre}. \end{note} \pnum -Except in the following cases, -if an indeterminate value is produced by an evaluation, -the behavior is undefined, and -if an erroneous value is produced by an evaluation, -the behavior is erroneous and -the result of the evaluation is the value so produced but is not erroneous: -\begin{itemize} -\item - If an indeterminate or erroneous value of - unsigned ordinary character type\iref{basic.fundamental} - or \tcode{std::byte} type\iref{cstddef.syn} - is produced by the evaluation of: - \begin{itemize} - \item - the second or third operand of a conditional expression\iref{expr.cond}, - \item - the right operand of a comma expression\iref{expr.comma}, - \item - the operand of a cast or conversion\iref{conv.integral, - expr.type.conv,expr.static.cast,expr.cast} - to an unsigned ordinary character type - or \tcode{std::byte} type\iref{cstddef.syn}, or - \item - a discarded-value expression\iref{expr.context}, - \end{itemize} - then the result of the operation is an indeterminate value or - that erroneous value, respectively. -\item - If an indeterminate or erroneous value of - unsigned ordinary character type or \tcode{std::byte} type - is produced by the evaluation of - the right operand of a simple assignment operator\iref{expr.ass} - whose first operand is an lvalue of - unsigned ordinary character type or \tcode{std::byte} type, - an indeterminate value or that erroneous value, respectively, replaces - the value of the object referred to by the left operand. -\item - If an indeterminate or erroneous value of unsigned ordinary character type - is produced by the evaluation of the initialization expression - when initializing an object of unsigned ordinary character type, - that object is initialized to an indeterminate - value or that erroneous value, respectively. -\item - If an indeterminate value of - unsigned ordinary character type or \tcode{std::byte} type - is produced by the evaluation of the initialization expression - when initializing an object of \tcode{std::byte} type, - that object is initialized to an indeterminate value or - that erroneous value, respectively. -\end{itemize} -Converting an indeterminate or erroneous value of -unsigned ordinary character type or \tcode{std::byte} type -produces an indeterminate or erroneous value, respectively. -In the latter case, -the result of the conversion is the value of the converted operand. +\indextext{signed integer representation!two's complement}% +An unsigned integer type has the same +object representation, +value representation, and +alignment requirements\iref{basic.align} +as the corresponding signed integer type. +For each value $x$ of a signed integer type, +the value of the corresponding unsigned integer type +congruent to $x$ modulo $2^N$ has the same value +of corresponding bits in its value representation. +\begin{footnote} +This +is also known as two's complement representation. +\end{footnote} \begin{example} -\begin{codeblock} -int f(bool b) { - unsigned char *c = new unsigned char; - unsigned char d = *c; // OK, \tcode{d} has an indeterminate value - int e = d; // undefined behavior - return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} -} - -int g(bool b) { - unsigned char c; - unsigned char d = c; // no erroneous behavior, but \tcode{d} has an erroneous value - - assert(c == d); // holds, both integral promotions have erroneous behavior - - int e = d; // erroneous behavior - return b ? d : 0; // erroneous behavior if \tcode{b} is \tcode{true} -} - -void h() { - int d1, d2; - - int e1 = d1; // erroneous behavior - int e2 = d1; // erroneous behavior - - assert(e1 == e2); // holds - assert(e1 == d1); // holds, erroneous behavior - assert(e2 == d1); // holds, erroneous behavior - - std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but \tcode{d2} has an erroneous value - assert(e1 == d2); // holds, erroneous behavior - assert(e2 == d2); // holds, erroneous behavior -} -\end{codeblock} +The value $-1$ of a signed integer type has the same representation as +the largest value of the corresponding unsigned type. \end{example} -\rSec2[basic.stc]{Storage duration} - -\rSec3[basic.stc.general]{General} +\begin{floattable}{Minimum width}{basic.fundamental.width}{lc} +\topline +\lhdr{Type} & \rhdr{Minimum width $N$} \\ +\capsep +\tcode{\keyword{signed} \keyword{char}} & 8 \\ +\tcode{\keyword{short} \keyword{int}} & 16 \\ +\keyword{int} & 16 \\ +\tcode{\keyword{long} \keyword{int}} & 32 \\ +\tcode{\keyword{long} \keyword{long} \keyword{int}} & 64 \\ +\end{floattable} \pnum -\indextext{storage duration|(}% -The \defn{storage duration} is the property of an object that defines the minimum -potential lifetime of the storage containing the object. The storage -duration is determined by the construct used to create the object and is -one of the following: -\begin{itemize} -\item static storage duration -\item thread storage duration -\item automatic storage duration -\item dynamic storage duration -\end{itemize} +The width of each standard signed integer type +shall not be less than the values specified in \tref{basic.fundamental.width}. +The value representation of a signed or unsigned integer type +comprises $N$ bits, where N is the respective width. +Each set of values for any padding bits\iref{basic.types.general} +in the object representation are +alternative representations of the value specified by the value representation. \begin{note} -After the duration of a region of storage has ended, -the use of pointers to that region of storage is limited\iref{basic.compound}. +Padding bits have unspecified value, but cannot cause traps. +In contrast, see \IsoC{} 6.2.6.2. +\end{note} +\begin{note} +The signed and unsigned integer types satisfy +the constraints given in \IsoC{} 5.2.4.2.1. \end{note} +Except as specified above, +the width of a signed or unsigned integer type is +\impldef{width of integral type}. \pnum -\indextext{storage duration!static}% -\indextext{storage duration!thread}% -\indextext{storage duration!automatic}% -\indextext{storage duration!dynamic}% -Static, thread, and automatic storage durations are associated with objects -introduced by declarations\iref{basic.def} and -with temporary objects\iref{class.temporary}. -The dynamic storage duration -is associated with objects created by a -\grammarterm{new-expression}\iref{expr.new} or -with implicitly created objects\iref{intro.object}. +Each value $x$ of an unsigned integer type with width $N$ has +a unique representation $x = x_0 2^0 + x_1 2^1 + \ldots + x_{N-1} 2^{N-1}$, +where each coefficient $x_i$ is either 0 or 1; +this is called the \defn{base-2 representation} of $x$. +The base-2 representation of a value of signed integer type is +the base-2 representation of the congruent value +of the corresponding unsigned integer type. +The standard signed integer types and standard unsigned integer types +are collectively called the \defnadjx{standard integer}{types}{type}, and the extended +signed integer types and extended +unsigned integer types are collectively called the +\defnadjx{extended integer}{types}{type}. \pnum -The storage duration categories apply to references as well. - -\rSec3[basic.stc.static]{Static storage duration} +A fundamental type specified to have +a signed or unsigned integer type as its \defnadj{underlying}{type} has +the same object representation, +value representation, +alignment requirements\iref{basic.align}, and +range of representable values as the underlying type. +Further, each value has the same representation in both types. \pnum -All variables which -\begin{itemize} -\item -do not have thread storage duration and -\item -belong to a namespace scope\iref{basic.scope.namespace} or -are first declared with -the \keyword{static} or \keyword{extern} keywords\iref{dcl.stc} -\end{itemize} -have \defnadj{static}{storage duration}. -The storage for these entities lasts for the duration of the -program\iref{basic.start.static,basic.start.term}. +\indextext{type!\idxcode{char}}% +\indextext{type!character}% +\indextext{\idxcode{char}!implementation-defined sign of}% +\indextext{type!\idxcode{signed char}}% +\indextext{character!\idxcode{signed}}% +\indextext{type!\idxcode{unsigned char}}% +Type \keyword{char} is a distinct type +that has an \impldef{underlying type of \tcode{char}} choice of +``\tcode{\keyword{signed} \keyword{char}}'' or ``\tcode{\keyword{unsigned} \keyword{char}}'' as its underlying type. +The three types \keyword{char}, \tcode{\keyword{signed} \keyword{char}}, and \tcode{\keyword{unsigned} \keyword{char}} +are collectively called +\defnadjx{ordinary character}{types}{type}. +The ordinary character types and \keyword{char8_t} +are collectively called \defnadjx{narrow character}{types}{type}. +For narrow character types, +each possible bit pattern of the object representation represents +a distinct value. +\begin{note} +This requirement does not hold for other types. +\end{note} +\begin{note} +A bit-field of narrow character type whose width is larger than +the width of that type has padding bits; see \ref{basic.types.general}. +\end{note} \pnum -If a variable with static storage duration has initialization or a -destructor with side effects, it shall not be eliminated even if it -appears to be unused, except that a class object or its copy/move may be -eliminated as specified in~\ref{class.copy.elision}. +\indextext{\idxcode{wchar_t}|see{type, \tcode{wchar_t}}}% +\indextext{type!\idxcode{wchar_t}}% +\indextext{type!underlying!\idxcode{wchar_t}}% +Type \keyword{wchar_t} is a distinct type that has +an \impldef{underlying type of \tcode{wchar_t}} +signed or unsigned integer type as its underlying type. + +\pnum +\indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% +\indextext{type!\idxcode{char8_t}}% +\indextext{type!underlying!\idxcode{char8_t}}% +Type \keyword{char8_t} denotes a distinct type +whose underlying type is \tcode{\keyword{unsigned} \keyword{char}}. +\indextext{\idxcode{char16_t}|see{type, \tcode{char16_t}}}% +\indextext{\idxcode{char32_t}|see{type, \tcode{char32_t}}}% +\indextext{type!\idxcode{char16_t}}% +\indextext{type!\idxcode{char32_t}}% +\indextext{type!underlying!\idxcode{char16_t}}% +\indextext{type!underlying!\idxcode{char32_t}}% +Types \keyword{char16_t} and \keyword{char32_t} denote distinct types +whose underlying types are \tcode{uint_least16_t} and \tcode{uint_least32_t}, +respectively, in \libheaderref{cstdint}. \pnum +\indextext{Boolean type}% +\indextext{type!Boolean}% +Type \tcode{bool} is a distinct type that has +the same object representation, +value representation, and +alignment requirements as +an \impldef{underlying type of \tcode{bool}} unsigned integer type. +The values of type \keyword{bool} are +\keyword{true} and \keyword{false}. \begin{note} -\indextext{object!local static@local \tcode{static}}% -The keyword \keyword{static} can be used to declare -a block variable\iref{basic.scope.block} with static storage duration; -\ref{stmt.dcl} and \ref{basic.start.term} describe the -initialization and destruction of such variables. -\indextext{member!class static@class \tcode{static}}% -The keyword \keyword{static} applied to -a class data member in a class definition -gives the data member static storage duration\iref{class.static.data}. +There are no \keyword{signed}, \keyword{unsigned}, +\keyword{short}, or \tcode{\keyword{long} \keyword{bool}} types or values. \end{note} -\rSec3[basic.stc.thread]{Thread storage duration} - \pnum -All variables declared with the \keyword{thread_local} keyword have -\defnadj{thread}{storage duration}. -The storage for these entities lasts for the duration of -the thread in which they are created. There is a distinct object or reference -per thread, and use of the declared name refers to the entity associated with -the current thread. +\indextext{type!integral}% +The types \keyword{char}, \keyword{wchar_t}, +\keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} +are collectively called \defnadjx{character}{types}{type}. +The character types, \keyword{bool}, +the signed and unsigned integer types, +and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{integral types}{integral type}. +A synonym for integral type is \defn{integer type}. +\begin{note} +Enumerations\iref{dcl.enum} are not integral; +however, unscoped enumerations can be promoted to integral types +as specified in \ref{conv.prom}. +\end{note} \pnum +\indextext{floating-point type|see{type, floating-point}}% +The three distinct types +\indextext{type!\idxcode{float}}% +\keyword{float}, +\indextext{type!\idxcode{double}}% +\keyword{double}, +and +\indextext{type!\idxcode{long double}}% +\tcode{\keyword{long} \keyword{double}} +can represent floating-point numbers. +The type \keyword{double} provides at least as much +precision as \keyword{float}, and the type \tcode{\keyword{long} \keyword{double}} provides at +least as much precision as \keyword{double}. The set of values of the type +\keyword{float} is a subset of the set of values of the type +\keyword{double}; the set of values of the type \keyword{double} is a subset +of the set of values of the type \tcode{\keyword{long} \keyword{double}}. +The types +\keyword{float}, \keyword{double}, and \tcode{\keyword{long} \keyword{double}}, +and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{standard floating-point types}{type!floating-point!standard}. +An implementation may also provide additional types +that represent floating-point values and define them (and cv-qualified versions thereof) to be +\defnx{extended floating-point types}{type!floating-point!extended}. +The standard and extended floating-point types +are collectively termed \defnx{floating-point types}{type!floating-point}. \begin{note} -A variable with thread storage duration is initialized as specified -in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and \ref{stmt.dcl} -and, if constructed, is destroyed on thread exit\iref{basic.start.term}. +Any additional implementation-specific types representing floating-point values +that are not defined by the implementation to be extended floating-point types +are not considered to be floating-point types, and +this document imposes no requirements on them or +their interactions with floating-point types. \end{note} - -\rSec3[basic.stc.auto]{Automatic storage duration} +Except as specified in \ref{basic.extended.fp}, +the object and value representations and accuracy of operations +of floating-point types are \impldef{representation of floating-point types}. \pnum -\indextext{storage duration!local object}% -Variables that belong to a block scope and are -not explicitly declared \keyword{static}, \keyword{thread_local}, or \keyword{extern} have -\defnadj{automatic}{storage duration}. The storage -for such variables lasts until the block in which they are created exits. +The minimum range of representable values for a floating-point type is +the most negative finite floating-point number representable +in that type through +the most positive finite floating-point number representable in that type. +In addition, if negative infinity is representable in a type, +the range of that type is extended to all negative real numbers; +likewise, if positive infinity is representable in a type, +the range of that type is extended to all positive real numbers. \begin{note} -These variables are initialized and destroyed as described in~\ref{stmt.dcl}. +Since negative and positive infinity are representable +in \IsoFloatUndated{} formats, +all real numbers lie within the range of representable values of +a floating-point type adhering to \IsoFloatUndated{}. \end{note} -Variables that belong to a parameter scope also have automatic storage duration. -The storage for a function parameter lasts until -immediately after its destruction\iref{expr.call}. \pnum -If a variable with automatic storage duration has initialization or a destructor with side -effects, an implementation shall not destroy it before the end of its block -nor eliminate it as an optimization, even if it appears to be -unused, except that a class object or its copy/move may be eliminated as -specified in~\ref{class.copy.elision}. +Integral and floating-point types are collectively +termed \defnx{arithmetic types}{type!arithmetic}. +\begin{note} +Properties of the arithmetic types, +such as their minimum and maximum representable value, +can be queried using the facilities in the standard library headers +\libheaderref{limits}, +\libheaderref{climits}, and +\libheaderref{cfloat}. +\end{note} -\rSec3[basic.stc.dynamic]{Dynamic storage duration}% +\pnum +\indextext{type!\idxcode{void}}% +A type \cv{}~\keyword{void} +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{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 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}, +\item the operand of a \keyword{decltype} specifier\iref{dcl.type.decltype}, or +\item the operand of an explicit conversion to type +\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. +\end{itemize} -\rSec4[basic.stc.dynamic.general]{General}% -\indextext{storage duration!dynamic|(} +\pnum +The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. +A value of type \tcode{std::nullptr_t} is a null pointer +constant\iref{conv.ptr}. Such values participate in the pointer and the +pointer-to-member conversions\iref{conv.ptr,conv.mem}. +\tcode{\keyword{sizeof}(std::nullptr_t)} shall be equal to \tcode{\keyword{sizeof}(\keyword{void}*)}. \pnum -Objects can be created dynamically during program -execution\iref{intro.execution}, using -\indextext{\idxcode{new}}% -\grammarterm{new-expression}{s}\iref{expr.new}, and destroyed using -\indextext{\idxcode{delete}}% -\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp{} implementation -provides access to, and management of, dynamic storage via -the global \defnx{allocation functions}{allocation function} -\tcode{\keyword{operator} \keyword{new}} and -\tcode{\keyword{operator} \keyword{new}[]} and -the global \defnx{deallocation functions}{deallocation function} -\tcode{\keyword{operator} \keyword{delete}} and -\tcode{\keyword{operator} \keyword{delete}[]}. +\indextext{type!fundamental}% +The types described in this subclause +are called \defnx{fundamental types}{fundamental type}. \begin{note} -The non-allocating forms described in \ref{new.delete.placement} -do not perform allocation or deallocation. +Even if the implementation defines two or more fundamental types to have the +same value representation, they are nevertheless different types. \end{note} -\pnum -The library provides default definitions for the global allocation and -deallocation functions. Some global allocation and deallocation -functions are replaceable\iref{new.delete}; -these are attached to the global module\iref{module.unit}. -A \Cpp{} program shall -provide at most one definition of a replaceable allocation or -deallocation function. Any such function definition replaces the default -version provided in the library\iref{replacement.functions}. The -following allocation and deallocation functions\iref{support.dynamic} -are implicitly declared in global scope in each translation unit of a -program. - -\begin{codeblock} -void* operator new(std::size_t); -void* operator new(std::size_t, std::align_val_t); +\rSec2[basic.extended.fp]{Optional extended floating-point types} -void operator delete(void*) noexcept; -void operator delete(void*, std::size_t) noexcept; -void operator delete(void*, std::align_val_t) noexcept; -void operator delete(void*, std::size_t, std::align_val_t) noexcept; - -void* operator new[](std::size_t); -void* operator new[](std::size_t, std::align_val_t); - -void operator delete[](void*) noexcept; -void operator delete[](void*, std::size_t) noexcept; -void operator delete[](void*, std::align_val_t) noexcept; -void operator delete[](void*, std::size_t, std::align_val_t) noexcept; -\end{codeblock} - -These implicit declarations introduce only the function names -\tcode{\keyword{operator} \keyword{new}}, -\tcode{\keyword{operator} \keyword{new}[]}, -\tcode{\keyword{operator} \keyword{delete}}, and -\tcode{\keyword{operator} \keyword{delete}[]}. -\begin{note} -The implicit declarations do not introduce -the names \tcode{std}, -\tcode{std::size_t}, -\tcode{std::align_val_t}, -or any other names that the library uses to -declare these names. Thus, a \grammarterm{new-expression}, -\grammarterm{delete-expression}, or function call that refers to one of -these functions without importing or including the header \libheaderref{new} -or importing a \Cpp{} library module\iref{std.modules} -is well-formed. However, referring to \tcode{std} -or \tcode{std::size_t} -or \tcode{std::align_val_t} -is ill-formed unless -a standard library declaration\iref{cstddef.syn,new.syn,std.modules} -of that name precedes\iref{basic.lookup.general} the use of that name. -\end{note} -Allocation and/or -deallocation functions may also be declared and defined for any -class\iref{class.free}. +\pnum +If the implementation supports an extended floating-point type\iref{basic.fundamental} +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary16, +then the \grammarterm{typedef-name} \tcode{std::float16_t} +is defined in the header \libheaderref{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT16_T} is defined\iref{cpp.predefined}, and +the floating-point literal suffixes \tcode{f16} and \tcode{F16} +are supported\iref{lex.fcon}. \pnum -If the behavior of an allocation or deallocation function -does not satisfy the semantic constraints -specified in~\ref{basic.stc.dynamic.allocation} -and~\ref{basic.stc.dynamic.deallocation}, -the behavior is undefined. - -\indextext{storage duration!dynamic|)} - -\rSec4[basic.stc.dynamic.allocation]{Allocation functions} +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary32, +then the \grammarterm{typedef-name} \tcode{std::float32_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT32_T} is defined, and +the floating-point literal suffixes \tcode{f32} and \tcode{F32} are supported. \pnum -\indextext{function!allocation}% -An allocation function that is not a class member function -shall belong to the global scope and not have a name with internal linkage. -The return type shall be \tcode{\keyword{void}*}. The first -parameter shall have type \tcode{std::size_t}\iref{support.types}. The -first parameter shall not have an associated default -argument\iref{dcl.fct.default}. The value of the first parameter -is interpreted as the requested size of the allocation. An allocation -function can be a function template. Such a template shall declare its -return type and first parameter as specified above (that is, template -parameter types shall not be used in the return type and first parameter -type). Allocation function templates shall have two or more parameters. +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary64, +then the \grammarterm{typedef-name} \tcode{std::float64_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT64_T} is defined, and +the floating-point literal suffixes \tcode{f64} and \tcode{F64} are supported. \pnum -An allocation function attempts to allocate the requested amount of -storage. If it is successful, it returns the address of the start -of a block of storage whose length in bytes is at least as large -as the requested size. -The order, -contiguity, and initial value of storage allocated by successive calls -to an allocation function are unspecified. -Even if the size of the space -requested is zero, the request can fail. If the request succeeds, the -value returned by a replaceable allocation function -is a non-null pointer value\iref{basic.compound} -\tcode{p0} different from any previously returned value \tcode{p1}, -unless that value \tcode{p1} was subsequently passed to a -replaceable deallocation function. -Furthermore, for the library allocation functions -in~\ref{new.delete.single} and~\ref{new.delete.array}, -\tcode{p0} represents the address of a block of storage disjoint from the storage -for any other object accessible to the caller. -The effect of indirecting through a pointer -returned from a request for zero size is undefined. -\begin{footnote} -The intent is -to have \tcode{\keyword{operator} \keyword{new}()} implementable by -calling \tcode{std::malloc()} or \tcode{std::calloc()}, so the rules are -substantially the same. \Cpp{} differs from C in requiring a zero request -to return a non-null pointer. -\end{footnote} +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary128, +then the \grammarterm{typedef-name} \tcode{std::float128_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT128_T} is defined, and +the floating-point literal suffixes \tcode{f128} and \tcode{F128} are supported. \pnum -For an allocation function other than -a reserved placement allocation function\iref{new.delete.placement}, -the pointer returned on a successful call -shall represent the address of storage that is aligned as follows: -\begin{itemize} -\item - If the allocation function takes an argument - of type \tcode{std::align_val_t}, - the storage will have the alignment specified - by the value of this argument. -\item - Otherwise, if the allocation function is named \tcode{\keyword{operator} \keyword{new}[]}, - the storage is aligned for any object that - does not have new-extended alignment\iref{basic.align} and - is no larger than the requested size. -\item - Otherwise, the storage is aligned for any object that - does not have new-extended alignment and is of the requested size. -\end{itemize} +If the implementation supports an extended floating-point type +with the properties, as specified by \IsoFloatUndated{}, of +radix ($b$) of 2, +storage width in bits ($k$) of 16, +precision in bits ($p$) of 8, +maximum exponent ($emax$) of 127, and +exponent field width in bits ($w$) of 8, then +the \grammarterm{typedef-name} \tcode{std::bfloat16_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_BFLOAT16_T} is defined, and +the floating-point literal suffixes \tcode{bf16} and \tcode{BF16} are supported. \pnum -An allocation function that fails to allocate storage can invoke the -currently installed new-handler function\iref{new.handler}, if any. \begin{note} -\indextext{\idxcode{new_handler}}% -A program-supplied allocation function can obtain the -currently installed \tcode{new_handler} using the -\tcode{std::get_new_handler} function\iref{get.new.handler}. +A summary of the parameters for each type is given in \tref{basic.extended.fp}. +The precision $p$ includes the implicit 1 bit at the beginning of the significand, +so the storage used for the significand is $p-1$ bits. +\IsoFloatUndated{} does not assign a name for a type +having the parameters specified for \tcode{std::bfloat16_t}. \end{note} -An allocation function that has a non-throwing -exception specification\iref{except.spec} -indicates failure by returning -a null pointer value. -Any other allocation function -never returns a null pointer value and -indicates failure only by throwing an exception\iref{except.throw} of a type -that would match a handler\iref{except.handle} of type -\tcode{std::bad_alloc}\iref{bad.alloc}. +\begin{floattable} +{Properties of named extended floating-point types}{basic.extended.fp}{llllll} +\topline +\lhdr{Parameter} & \chdr{\tcode{float16_t}} & \chdr{\tcode{float32_t}} & +\chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & +\rhdr{\tcode{bfloat16_t}} \\ +\capsep +\IsoFloatUndated{} name & binary16 & binary32 & binary64 & binary128 & \\ +$k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ +$p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ +$emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ +$w$, exponent field width in bits & 5 & 8 & 11 & 15 & 8 \\ +\end{floattable} \pnum -A global allocation function is only called as the result of a new -expression\iref{expr.new}, or called directly using the function call -syntax\iref{expr.call}, or called indirectly to allocate storage for -a coroutine state\iref{dcl.fct.def.coroutine}, -or called indirectly through calls to the -functions in the \Cpp{} standard library. -\begin{note} -In particular, a -global allocation function is not called to allocate storage for objects -with static storage duration\iref{basic.stc.static}, for objects or references -with thread storage duration\iref{basic.stc.thread}, for objects of -type \tcode{std::type_info}\iref{expr.typeid}, or for an -exception object\iref{except.throw}. -\end{note} +\recommended +Any names that the implementation provides for +the extended floating-point types described in this subsection +that are in addition to the names defined in the \libheader{stdfloat} header +should be chosen to increase compatibility and interoperability +with the interchange types +\tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} +defined in ISO/IEC TS 18661-3 and with future versions of \IsoCUndated{}. -\rSec4[basic.stc.dynamic.deallocation]{Deallocation functions} +\rSec2[conv.rank]{Conversion ranks}% +\indextext{conversion!integer rank} \pnum -\indextext{function!deallocation}% -A deallocation function that is not a class member function -shall belong to the global scope and not have a name with internal linkage. +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 +the same representation. + +\item The rank of a signed integer type is greater than the rank +of any signed integer type with a smaller width. + +\item The rank of \tcode{\keyword{long} \keyword{long} \keyword{int}} is greater +than the rank of \tcode{\keyword{long} \keyword{int}}, which is greater than +the rank of \keyword{int}, which is greater than the rank of +\tcode{\keyword{short} \keyword{int}}, which is greater than the rank of +\tcode{\keyword{signed} \keyword{char}}. + +\item The rank of any unsigned integer type equals the rank of the +corresponding signed integer type. + +\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. + +\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 +types\iref{basic.fundamental}. + +\item The rank of any extended signed integer type relative to another +extended signed integer type with the same width is \impldef{rank of extended signed +integer type}, but still subject to the other rules for determining the integer +conversion rank. + +\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if +\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater +rank than \tcode{T3}, then \tcode{T1} has greater rank than +\tcode{T3}. +\end{itemize} -\pnum -A deallocation function -is a \defnadj{destroying}{operator delete} -if it has at least two parameters -and its second parameter -is of type \tcode{std::destroying_delete_t}. -A destroying operator delete -shall be a class member function named \tcode{\keyword{operator} \keyword{delete}}. \begin{note} -Array deletion cannot use a destroying operator delete. +The integer conversion rank is used in the definition of the integral +promotions\iref{conv.prom} and the usual arithmetic +conversions\iref{expr.arith.conv}. \end{note} \pnum -\indextext{\idxcode{delete}!overloading and}% -Each deallocation function shall return \keyword{void}. -If the function is a destroying operator delete -declared in class type \tcode{C}, -the type of its first parameter shall be \tcode{C*}; -otherwise, the type of its first -parameter shall be \tcode{\keyword{void}*}. A deallocation function may have more -than one parameter. -\indextext{deallocation function!usual}% -A \defn{usual deallocation function} is a deallocation function -whose parameters after the first are +Every floating-point type has a \defnadj{floating-point}{conversion rank} +defined as follows: \begin{itemize} \item -optionally, a parameter of type \tcode{std::destroying_delete_t}, then +The rank of a floating point type \tcode{T} is greater than +the rank of any floating-point type +whose set of values is a proper subset of the set of values of \tcode{T}. \item -optionally, a parameter of type \tcode{std::size_t}, -\begin{footnote} -The global \tcode{\keyword{operator} \keyword{delete}(\keyword{void}*, std::size_t)} -precludes use of an -allocation function \tcode{\keyword{void} \keyword{operator} \keyword{new}(std::size_t, std::size_t)} as a placement -allocation function\iref{diff.cpp11.basic}. -\end{footnote} -then +The rank of \tcode{\keyword{long} \keyword{double}} is greater than +the rank of \keyword{double}, +which is greater than the rank of \keyword{float}. \item -optionally, a parameter of type \tcode{std::align_val_t}. +Two extended floating-point types with the same set of values have equal ranks. +\item +An extended floating-point type with the same set of values as +exactly one cv-unqualified standard floating-point type +has a rank equal to the rank of that standard floating-point type. +\item +An extended floating-point type with the same set of values as +more than one cv-unqualified standard floating-point type +has a rank equal to the rank of \keyword{double}. +\begin{tailnote} +The treatment of \tcode{std::float64_t} differs from +that of the analoguous \tcode{_Float64} in C, +for example on platforms where all of +\tcode{\keyword{long} \keyword{double}}, +\keyword{double}, and +\tcode{std::float64_t} +have the same set of values (see \IsoCUndated{}:2024 H.4.2). +\end{tailnote} \end{itemize} -A destroying operator delete shall be a usual deallocation function. -A deallocation function may be an instance of a function -template. Neither the first parameter nor the return type shall depend -on a template parameter. -A deallocation -function template shall have two or more function parameters. A template -instance is never a usual deallocation function, regardless of its -signature. +\begin{note} +The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} +are unordered if the set of values of \tcode{T1} is +neither a subset nor a superset of the set of values of \tcode{T2}. +This can happen when one type has both a larger range and a lower precision +than the other. +\end{note} \pnum -If a deallocation function terminates by throwing an exception, the behavior is undefined. -The value of the first argument supplied to a deallocation function may -be a null pointer value; if so, and if the deallocation function is one -supplied in the standard library, the call has no effect. +Floating-point types that have equal floating-point conversion ranks +are ordered by floating-point conversion subrank. +The subrank forms a total order among types with equal ranks. +The types +\tcode{std::float16_t}, +\tcode{std::float32_t}, +\tcode{std::float64_t}, and +\tcode{std::float128_t}\iref{stdfloat.syn} +have a greater conversion subrank than any standard floating-point type +with equal conversion rank. +Otherwise, the conversion subrank order is +\impldef{floating-point conversion subrank}. \pnum -If the argument given to a deallocation function in the standard library -is a pointer that is not the null pointer value\iref{basic.compound}, the -deallocation function shall deallocate the storage referenced by the -pointer, ending the duration of the region of storage. +\begin{note} +The floating-point conversion rank and subrank are used in +the definition of the usual arithmetic conversions\iref{expr.arith.conv}. +\end{note} -\rSec3[basic.stc.inherit]{Duration of subobjects} +\rSec2[basic.compound]{Compound types} \pnum -\indextext{storage duration!class member}% -The storage duration of subobjects and reference members -is that of their complete object\iref{intro.object}. -\indextext{storage duration|)}% - -\rSec2[basic.align]{Alignment} +\indextext{type!compound}% +Compound types can be constructed in the following ways: +\begin{itemize} +\item \defnx{arrays}{type!array} of objects of a given type, \ref{dcl.array}; -\pnum -Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}\iref{basic.fundamental,basic.compound} -which place restrictions on the addresses at which an object of that type -may be allocated. An \defn{alignment} is an \impldef{alignment} -integer value representing the number of bytes between successive addresses -at which a given object can be allocated. An object type imposes an alignment -requirement on every object of that type; stricter alignment can be requested -using the alignment specifier\iref{dcl.align}. -Attempting to create an object\iref{intro.object} in storage that -does not meet the alignment requirements of the object's type -is undefined behavior. +\item \defnx{functions}{type!function}, which have parameters of given types and return +\keyword{void} or references or objects of a given type, \ref{dcl.fct}; -\pnum -A \defnadj{fundamental}{alignment} is represented by an alignment -less than or equal to the greatest alignment supported by the implementation in -all contexts, which is equal to -\tcode{\keyword{alignof}(std::max_align_t)}\iref{support.types}. -The alignment required for a type may be different when it is used as the type -of a complete object and when it is used as the type of a subobject. -\begin{example} -\begin{codeblock} -struct B { long double d; }; -struct D : virtual B { char c; }; -\end{codeblock} +\item \defnx{pointers}{type!pointer} to \cv{}~\keyword{void} or objects or functions (including +static members of classes) of a given type, \ref{dcl.ptr}; -When \tcode{D} is the type of a complete object, it will have a subobject of -type \tcode{B}, so it must be aligned appropriately for a \tcode{\keyword{long} \keyword{double}}. -If \tcode{D} appears as a subobject of another object that also has \tcode{B} -as a virtual base class, the \tcode{B} subobject might be part of a different -subobject, reducing the alignment requirements on the \tcode{D} subobject. -\end{example} -The result of the \keyword{alignof} operator reflects the alignment -requirement of the type in the complete-object case. +\item +\indextext{reference!lvalue}% +\indextext{reference!rvalue}% +\defnx{references}{reference} to objects or functions of a given +type, \ref{dcl.ref}. There are two types of references: +\begin{itemize} +\item lvalue reference +\item rvalue reference +\end{itemize} -\pnum -An \defnadj{extended}{alignment} is represented by an alignment -greater than \tcode{\keyword{alignof}(std::max_align_t)}. It is \impldef{support for extended alignments} -whether any extended alignments are supported and the contexts in which they are -supported\iref{dcl.align}. A type having an extended alignment -requirement is an \defnadj{over-aligned}{type}. -\begin{note} -Every over-aligned type is or contains a class type -to which extended alignment applies (possibly through a non-static data member). -\end{note} -A \defnadj{new-extended}{alignment} is represented by -an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. +\item +\defnx{classes}{class} containing a sequence of objects of various types\iref{class}, +a set of types, enumerations and functions for +manipulating these objects\iref{class.mfct}, and a set of restrictions +on the access to these entities\iref{class.access}; -\pnum -Alignments are represented as values of the type \tcode{std::size_t}. -Valid alignments include only those values returned by an \keyword{alignof} -expression for the fundamental types plus an additional \impldef{alignment additional -values} -set of values, which may be empty. -Every alignment value shall be a non-negative integral power of two. +\item +\defnx{unions}{\idxcode{union}}, which are classes capable of containing objects of +different types at different times, \ref{class.union}; -\pnum -Alignments have an order from \defnx{weaker}{alignment!weaker} to -\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter -alignments have larger alignment values. An address that satisfies an alignment -requirement also satisfies any weaker valid alignment requirement. +\item +\defnx{enumerations}{\idxcode{enum}}, +which comprise a set of named constant values, \ref{dcl.enum}; -\pnum -The alignment requirement of a complete type can be queried using an -\keyword{alignof} expression\iref{expr.alignof}. Furthermore, -the narrow character types\iref{basic.fundamental} shall have the weakest -alignment requirement. -\begin{note} -This enables the ordinary character types to be used as the -underlying type for an aligned memory area\iref{dcl.align}. -\end{note} +\item +\indextext{member pointer to|see{pointer to member}}% +\defnx{pointers to non-static class members}{pointer to member},% +\begin{footnote} +Static class members are objects or functions, and pointers to them are +ordinary pointers to objects or functions. +\end{footnote} +which identify members of a given +type within objects of a given class, \ref{dcl.mptr}. +Pointers to data members and pointers to member functions are collectively +called \term{pointer-to-member} types. +\end{itemize} \pnum -Comparing alignments is meaningful and provides the obvious results: - -\begin{itemize} -\item Two alignments are equal when their numeric values are equal. -\item Two alignments are different when their numeric values are not equal. -\item When an alignment is larger than another it represents a stricter alignment. -\end{itemize} +These methods of constructing types can be applied recursively; +restrictions are mentioned in~\ref{dcl.meaning}. +Constructing a type such that the number of +bytes in its object representation exceeds the maximum value representable in +the type \tcode{std::size_t}\iref{support.types} is ill-formed. \pnum +\indextext{terminology!pointer}% +The type of a pointer to \cv{}~\keyword{void} or a pointer to an object type is +called an \defn{object pointer type}. \begin{note} -The runtime pointer alignment function\iref{ptr.align} -can be used to obtain an aligned pointer within a buffer; -an \grammarterm{alignment-specifier}\iref{dcl.align} -can be used to align storage explicitly. +A pointer to \keyword{void} +does not have a pointer-to-object type, however, because \keyword{void} is not +an object type. \end{note} - -\pnum -If a request for a specific extended alignment in a specific context is not -supported by an implementation, the program is ill-formed. - -\rSec2[class.temporary]{Temporary objects} - -\pnum -\indextext{object temporary|see{temporary}}% -\indextext{temporary}% -\indextext{optimization of temporary|see{temporary, elimination of}}% -\indextext{temporary!elimination of}% -\indextext{temporary!implementation-defined generation of}% -Temporary objects are created +The type of a pointer that can designate a function +is called a \defn{function pointer type}. +A pointer to an object of type \tcode{T} is referred to as a ``pointer to +\tcode{T}''. +\begin{example} +A pointer to an object of type \keyword{int} is +referred to as ``pointer to \keyword{int}'' and a pointer to an object of +class \tcode{X} is called a ``pointer to \tcode{X}''. +\end{example} +Except for pointers to static members, text referring to ``pointers'' +does not apply to pointers to members. Pointers to incomplete types are +allowed although there are restrictions on what can be done with +them\iref{basic.types.general}. +\indextext{address}% +Every value of pointer type is one of the following: \begin{itemize} \item -when a prvalue is converted to an xvalue\iref{conv.rval} and +a \defn{pointer to} an object or function (the pointer is said to \defn{point} to the object or function), or \item -when needed by the implementation to pass or return an object of trivially copyable type (see below). +a \defn{pointer past the end of} an object\iref{expr.add}, or +\item +\indextext{null pointer value|see{value, null pointer}} +the \defnx{null pointer value}{value!null pointer} for that type, or +\item +\indextext{invalid pointer value|see{value, invalid pointer}} +an \defnx{invalid pointer value}{value!invalid pointer}. \end{itemize} -Even when the creation of the temporary object is -unevaluated\iref{expr.context}, -all the semantic restrictions shall be respected as if the temporary object -had been created and later destroyed. +A value of a +pointer type +that is a pointer to or past the end of an object +\defn{represents the address} of +the first byte in memory\iref{intro.memory} occupied by the object +\begin{footnote} +For an object that is not within its lifetime, +this is the first byte in memory that it will occupy or used to occupy. +\end{footnote} +or the first byte in memory +after the end of the storage occupied by the object, +respectively. \begin{note} -This includes accessibility\iref{class.access} and whether it is deleted, -for the constructor selected and for the destructor. However, in the special -case of the operand of a -\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, no temporary is introduced, -so the foregoing does not apply to such a prvalue. +A pointer past the end of an object\iref{expr.add} +is not considered to point to an unrelated object +of the object's type, +even if the unrelated object is located at that address. +\end{note} +For purposes of pointer arithmetic\iref{expr.add} +and comparison\iref{expr.rel,expr.eq}, +a pointer past the end of the last element of +an array \tcode{x} of $n$ elements +is considered to be equivalent to +a pointer to a hypothetical array element $n$ of \tcode{x} and +an object of type \tcode{T} that is not an array element +is considered to belong to an array with one element of type \tcode{T}. +The value representation of +pointer types is \impldef{value representation of pointer types}. Pointers to +layout-compatible types shall +have the same value representation and alignment +requirements\iref{basic.align}. +\begin{note} +Pointers to over-aligned types\iref{basic.align} have no special +representation, but their range of valid values is restricted by the extended +alignment requirement. \end{note} \pnum -The materialization of a temporary object is generally -delayed as long as possible -in order to avoid creating unnecessary temporary objects. +A pointer value $P$ is +\indextext{value!valid in the context of an evaluation}% +\defn{valid in the context of} an evaluation $E$ +if $P$ is a null pointer value, or +if it is a pointer to or past the end of an object $O$ and +$E$ happens before the end of the duration of the region of storage for $O$. +If a pointer value $P$ is used in an evaluation $E$ and +$P$ is not valid in the context of $E$, +then the behavior is undefined if $E$ is +an indirection\iref{expr.unary.op} or +an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation}, +and \impldef{invalid pointer value in the context of an evaluation} otherwise. +\begin{footnote} +Some implementations might define that +copying such a pointer value causes a system-generated runtime fault. +\end{footnote} \begin{note} -Temporary objects are materialized: +$P$ can be valid in the context of $E$ even +if it points to a type unrelated to that of $O$ or +if $O$ is not within its lifetime, +although further restrictions apply +to such pointer values\iref{basic.life, basic.lval, expr.add}. +\end{note} + +\pnum +Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if \begin{itemize} \item -when binding a reference to a prvalue\iref{dcl.init.ref,expr.type.conv, -expr.dynamic.cast,expr.static.cast,expr.const.cast,expr.cast}, -\item -when performing certain member accesses on a class prvalue\iref{expr.ref,expr.mptr.oper}, -\item -when invoking an implicit object member function on a class prvalue\iref{expr.call}, -\item -when performing an array-to-pointer conversion or subscripting on an array prvalue\iref{conv.array,expr.sub}, +they are the same object, or \item -when initializing an object of type \tcode{std::initializer_list} from a \grammarterm{braced-init-list}\iref{dcl.init.list}, +one is a union object and +the other is a non-static data member of that object\iref{class.union}, or \item -for certain unevaluated operands\iref{expr.typeid,expr.sizeof}, and +one is a standard-layout class object and +the other is the first non-static data member of that object or +any base class subobject of that object\iref{class.mem}, or \item -when a prvalue that has type other than \cv{}~\keyword{void} appears as a discarded-value expression\iref{expr.context}. +there exists an object \placeholder{c} such that +\placeholder{a} and \placeholder{c} are pointer-interconvertible, and +\placeholder{c} and \placeholder{b} are pointer-interconvertible. \end{itemize} +If two objects are pointer-interconvertible, +then they have the same address, +and it is possible to obtain a pointer to one +from a pointer to the other +via a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}. +\begin{note} +An array object and its first element are not pointer-interconvertible, +even though they have the same address. \end{note} -\begin{example} -Consider the following code: -\begin{codeblock} -class X { -public: - X(int); - X(const X&); - X& operator=(const X&); - ~X(); -}; - -class Y { -public: - Y(int); - Y(Y&&); - ~Y(); -}; - -X f(X); -Y g(Y); - -void h() { - X a(1); - X b = f(X(2)); - Y c = g(Y(3)); - a = f(a); -} -\end{codeblock} - -\indextext{class object copy|see{constructor, copy}}% -\indextext{constructor!copy}% -\tcode{X(2)} is constructed in the space used to hold \tcode{f()}'s argument and -\tcode{Y(3)} is constructed in the space used to hold \tcode{g()}'s argument. -Likewise, -\tcode{f()}'s result is constructed directly in \tcode{b} and -\tcode{g()}'s result is constructed directly in \tcode{c}. -On the other hand, the expression -\tcode{a = f(a)} -requires a temporary for -the result of \tcode{f(a)}, -which is materialized so that the reference parameter -of \tcode{X::operator=(const X\&)} can bind to it. -\end{example} \pnum -When an object of class type \tcode{X} -is passed to or returned from a potentially-evaluated function call, -if \tcode{X} has at least one eligible copy or move constructor\iref{special}, -each such constructor is trivial, -and the destructor of \tcode{X} is either trivial or deleted, -implementations are permitted -to create a temporary object -to hold the function parameter or result object. -The temporary object is constructed -from the function argument or return value, respectively, -and the function's parameter or return object -is initialized as if by -using the eligible trivial constructor to copy the temporary -(even if that constructor is inaccessible -or would not be selected by overload resolution -to perform a copy or move of the object). -\begin{note} -This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. -\end{note} +A byte of storage \placeholder{b} +is \defnx{reachable through}{storage!reachable through a pointer value} +a pointer value that points to an object \placeholder{x} +if there is an object \placeholder{y}, +pointer-interconvertible with \placeholder{x}, +such that \placeholder{b} is within the storage occupied by +\placeholder{y}, or the immediately-enclosing array object +if \placeholder{y} is an array element. \pnum -\indextext{temporary!constructor for}% -\indextext{temporary!destructor for}% -\indextext{temporary!destruction of}% -Temporary objects are destroyed as the last step -in evaluating -the full-expression\iref{intro.execution} -that (lexically) contains the point where -they were created. -This is true even if that evaluation ends in throwing an exception. -The -\indextext{value computation}% -value computations and -\indextext{side effects}% -side effects of destroying a temporary object -are associated only with the full-expression, not with any specific -subexpression. +\indextext{pointer|seealso{\tcode{void*}}}% +\indextext{\idxcode{void*}!type}% +A pointer to \cv{}~\keyword{void} +can be used to point to objects of +unknown type. Such a pointer shall be able to hold any object pointer. +An object of type ``pointer to \cv{}~\keyword{void}'' +shall have the same representation and alignment +requirements as an object of type ``pointer to \cv{}~\keyword{char}''. + +\rSec1[basic.def]{Declarations and definitions} \pnum -\indextext{initializer!temporary and declarator}% -\indextext{temporary!order of destruction of}% -There are five contexts in which temporaries are destroyed at a different -point than the end of the full-expression. -The first context is when a default constructor is called to initialize -an element of an array with no corresponding initializer\iref{dcl.init}. -The second context is when a copy constructor is called to copy an element of -an array while the entire array is copied\iref{expr.prim.lambda.capture,class.copy.ctor}. -In either case, if the constructor has one or more default arguments, -the destruction of every temporary created in a default argument is -sequenced before the construction of the next array element, if any. +\indextext{declaration!definition versus}% +\indextext{declaration}% +\indextext{declaration!name}% +A declaration\iref{dcl} may (re)introduce +one or more names and/or entities into a translation +unit. +If so, the +declaration specifies the interpretation and semantic properties of these names. +A declaration of an entity or \grammarterm{typedef-name} $X$ is +a redeclaration of $X$ +if another declaration of $X$ is reachable from it\iref{module.reach}. +A declaration may also have effects including: +\begin{itemize} +\item nothing (in the case of an \grammarterm{empty-declaration}), +\item a static assertion\iref{dcl.pre}, +\item use of attributes\iref{dcl.attr}, +\item guiding template argument deduction for constructors\iref{temp.deduct.guide}, and +\item controlling template instantiation\iref{temp.explicit}. +\end{itemize} \pnum -The third context is when a reference binds to a temporary object. -\begin{footnote} -The same rules apply to initialization of an - \tcode{initializer_list} object\iref{dcl.init.list} with its - underlying temporary array. -\end{footnote} -The temporary object to which the reference is bound or the temporary object -that is the complete object of a subobject to which the reference is bound -persists for the lifetime of the reference if the glvalue -to which the reference is bound -was obtained through one of the following: +\indextext{declaration!function}% +\indextext{definition}% +Each entity declared by a \grammarterm{declaration} is +also \defnx{defined}{define} by that declaration unless: \begin{itemize} +\item it is +a \grammarterm{static_assert-declaration}\iref{dcl.pre}, \item - a temporary materialization conversion\iref{conv.rval}, -\item - \tcode{(} \grammarterm{expression} \tcode{)}, - where \grammarterm{expression} is one of these expressions, -\item - subscripting\iref{expr.sub} of an array operand, - where that operand is one of these expressions, -\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, +it is an +\grammarterm{attribute-declaration}\iref{dcl.pre}, \item - a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator - where the left operand is one of these expressions and - the right operand is a pointer to data member of non-reference type, +it is an +\grammarterm{empty-declaration}\iref{dcl.pre}, \item - a - \begin{itemize} - \item \keyword{const_cast}\iref{expr.const.cast}, - \item \keyword{static_cast}\iref{expr.static.cast}, - \item \keyword{dynamic_cast}\iref{expr.dynamic.cast}, or - \item \keyword{reinterpret_cast}\iref{expr.reinterpret.cast} - \end{itemize} - converting, without a user-defined conversion, - a glvalue operand that is one of these expressions - to a glvalue that refers - to the object designated by the operand, or - to its complete object or a subobject thereof, +it contains +the +\indextext{declaration!\idxcode{extern}}% +\keyword{extern} specifier\iref{dcl.stc} or a +\grammarterm{linkage-specification} +\begin{footnote} +Appearing inside the brace-enclosed +\grammarterm{declaration-seq} in a \grammarterm{linkage-specification} does +not affect whether a declaration is a definition. +\end{footnote} +\iref{dcl.link} +and neither an \grammarterm{initializer} nor a +\grammarterm{function-body}, \item - a conditional expression\iref{expr.cond} that is a glvalue - where the second or third operand is one of these expressions, or +it is a +\indextext{declaration!\idxcode{typedef}}% +\keyword{typedef} declaration\iref{dcl.typedef}, +\item it is +an \grammarterm{alias-declaration}\iref{dcl.typedef}, \item - a comma expression\iref{expr.comma} that is a glvalue - where the right operand is one of these expressions. +it is a +\indextext{declaration!parameter}\indextext{parameter declaration}% +\grammarterm{parameter-declaration}\iref{dcl.fct} in a function +\indextext{declarator}% +declarator that is not the \grammarterm{declarator} of a +\grammarterm{function-definition}, +\item +it declares a function +without specifying the function's body\iref{dcl.fct.def}, +\item +it is an +\indextext{declaration!opaque enum}% +\grammarterm{opaque-enum-declaration}\iref{dcl.enum}, +\item it is +a \grammarterm{using-enum-declaration}\iref{enum.udecl}, +\item it is +a \grammarterm{using-directive}\iref{namespace.udir}, +\item it is +a +\grammarterm{using-declaration}\iref{namespace.udecl}, +\item +\indextext{declaration!class name}% +it is an \grammarterm{elaborated-type-specifier}\iref{class.name}, +\item +\indextext{declaration!static member@\tcode{static} member}% +it declares a non-inline static data member in a class +definition\iref{class.mem,class.static}, +\item +it declares a static data member outside a class definition +and the variable was defined within the class with the \keyword{constexpr} +specifier\iref{class.static.data} (this usage is deprecated; see \ref{depr.static.constexpr}), +\item it is +a \grammarterm{template-declaration}\iref{temp.pre} +whose \grammarterm{template-head} is not followed by +either a \grammarterm{concept-definition} or a \grammarterm{declaration} +that defines a function, a class, a variable, or a static data member, +\item +it is a +\indextext{parameter!template}\indextext{template parameter}% +\grammarterm{template-parameter}\iref{temp.param}, +\item it is +a \grammarterm{deduction-guide}\iref{temp.deduct.guide}, +\item it is +an explicit instantiation declaration\iref{temp.explicit}, or +\item it is +an explicit specialization\iref{temp.expl.spec} whose +\grammarterm{declaration} is not a definition. \end{itemize} +A declaration is said to be a \defn{definition} of each entity that it defines. \begin{example} +All but one of the following are definitions: \begin{codeblock} -template using id = T; +int a; // defines \tcode{a} +extern const int c = 1; // defines \tcode{c} +int f(int x) { return x+a; } // defines \tcode{f} and defines \tcode{x} +struct S { int a; int b; }; // defines \tcode{S}, \tcode{S::a}, and \tcode{S::b} +struct X { // defines \tcode{X} + int x; // defines non-static data member \tcode{x} + static int y; // declares static data member \tcode{y} + X(): x(0) { } // defines a constructor of \tcode{X} +}; +int X::y = 1; // defines \tcode{X::y} +enum { up, down }; // defines \tcode{up} and \tcode{down} +namespace N { int d; } // defines \tcode{N} and \tcode{N::d} +namespace N1 = N; // defines \tcode{N1} +X anX; // defines \tcode{anX} -int i = 1; -int&& a = id{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} -const int& b = static_cast(0); // temporary \tcode{int} has same lifetime as \tcode{b} -int&& c = cond ? id{1, 2, 3}[i] : static_cast(0); - // exactly one of the two temporaries is lifetime-extended \end{codeblock} -\end{example} -\begin{note} -An explicit type conversion\iref{expr.type.conv,expr.cast} -is interpreted as -a sequence of elementary casts, -covered above. -\begin{example} -\begin{codeblock} -const int& x = (const int&)1; // temporary for value 1 has same lifetime as x -\end{codeblock} -\end{example} -\end{note} -\begin{note} -If a temporary object has a reference member initialized by another temporary object, -lifetime extension applies recursively to such a member's initializer. -\begin{example} +whereas these are just declarations: \begin{codeblock} -struct S { - const int& m; -}; -const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} +extern int a; // declares \tcode{a} +extern const int c; // declares \tcode{c} +int f(int); // declares \tcode{f} +struct S; // declares \tcode{S} +typedef int Int; // declares \tcode{Int} +extern X anotherX; // declares \tcode{anotherX} +using N::d; // declares \tcode{d} \end{codeblock} \end{example} -\end{note} -The exceptions to this lifetime rule are: -\begin{itemize} -\item A temporary object bound to a reference parameter in a function call\iref{expr.call} -persists until the completion of the full-expression containing the call. - -\item A temporary object bound to a reference element of -an aggregate of class type initialized from -a parenthesized \grammarterm{expression-list}\iref{dcl.init} -persists until the completion of the full-expression -containing the \grammarterm{expression-list}. - -\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. +\pnum \begin{note} -This might introduce a dangling reference. +\indextext{implementation-generated}% +In some circumstances, \Cpp{} implementations implicitly define the +default constructor\iref{class.default.ctor}, +copy constructor, move constructor\iref{class.copy.ctor}, +copy assignment operator, move assignment operator\iref{class.copy.assign}, +or destructor\iref{class.dtor} member functions. \end{note} \begin{example} -\begin{codeblock} -struct S { int mi; const std::pair& mp; }; -S a { 1, {2,3} }; -S* p = new S{ 1, {2,3} }; // creates dangling reference -\end{codeblock} -\end{example} -\end{itemize} - -\pnum -The fourth context is when a temporary object -is created in the \grammarterm{for-range-initializer} of a range-based \keyword{for} statement. -If such a temporary object would otherwise be destroyed -at the end of the \grammarterm{for-range-initializer} full-expression, -the object persists for the lifetime of the reference -initialized by the \grammarterm{for-range-initializer}. - -\pnum -The fifth context is when a temporary object -is created in a structured binding declaration\iref{dcl.struct.bind}. -Any temporary objects introduced by -the \grammarterm{initializer}{s} for the variables -with unique names -are destroyed at the end of the structured binding declaration. - -\pnum -Let \tcode{x} and \tcode{y} each be either -a temporary object whose lifetime is not extended, or -a function parameter. -If the lifetimes of \tcode{x} and \tcode{y} end at -the end of the same full-expression, and -\tcode{x} is initialized before \tcode{y}, then -the destruction of \tcode{y} is sequenced before that of \tcode{x}. -If the lifetime of two or more temporaries -with lifetimes extending beyond the full-expressions in which they were created -ends at the same point, -these temporaries are destroyed at that point in the reverse order of the -completion of their construction. -In addition, the destruction of such temporaries shall -take into account the ordering of destruction of objects with static, thread, or -automatic storage duration\iref{basic.stc.static,basic.stc.thread,basic.stc.auto}; -that is, if -\tcode{obj1} -is an object with the same storage duration as the temporary and -created before the temporary is created -the temporary shall be destroyed before -\tcode{obj1} -is destroyed; -if -\tcode{obj2} -is an object with the same storage duration as the temporary and -created after the temporary is created -the temporary shall be destroyed after -\tcode{obj2} -is destroyed. - -\pnum -\begin{example} -\begin{codeblock} -struct S { - S(); - S(int); - friend S operator+(const S&, const S&); - ~S(); -}; -S obj1; -const S& cr = S(16)+S(23); -S obj2; -\end{codeblock} - -The expression -\tcode{S(16) + S(23)} -creates three temporaries: -a first temporary -\tcode{T1} -to hold the result of the expression -\tcode{S(16)}, -a second temporary -\tcode{T2} -to hold the result of the expression -\tcode{S(23)}, -and a third temporary -\tcode{T3} -to hold the result of the addition of these two expressions. -The temporary -\tcode{T3} -is then bound to the reference -\tcode{cr}. -It is unspecified whether -\tcode{T1} -or -\tcode{T2} -is created first. -On an implementation where -\tcode{T1} -is created before -\tcode{T2}, -\tcode{T2} -shall be destroyed before -\tcode{T1}. -The temporaries -\tcode{T1} -and -\tcode{T2} -are bound to the reference parameters of -\tcode{\keyword{operator}+}; -these temporaries are destroyed at the end of the full-expression -containing the call to -\tcode{\keyword{operator}+}. -The temporary -\tcode{T3} -bound to the reference -\tcode{cr} -is destroyed at the end of -\tcode{cr}'s -lifetime, that is, at the end of the program. -In addition, the order in which -\tcode{T3} -is destroyed takes into account the destruction order of other objects with -static storage duration. -That is, because -\tcode{obj1} -is constructed before -\tcode{T3}, -and -\tcode{T3} -is constructed before -\tcode{obj2}, -\tcode{obj2} -shall be destroyed before -\tcode{T3}, -and -\tcode{T3} -shall be destroyed before -\tcode{obj1}. +Given +\begin{codeblock} +#include + +struct C { + std::string s; // \tcode{std::string} is the standard library class\iref{string.classes} +}; + +int main() { + C a; + C b = a; + b = a; +} +\end{codeblock} +the implementation will implicitly define functions to make the +definition of \tcode{C} equivalent to +\begin{codeblock} +struct C { + std::string s; + C() : s() { } + C(const C& x): s(x.s) { } + C(C&& x): s(static_cast(x.s)) { } + @\rlap{\textnormal{\textit{//}}}@ : s(std::move(x.s)) { } + C& operator=(const C& x) { s = x.s; return *this; } + C& operator=(C&& x) { s = static_cast(x.s); return *this; } + @\rlap{\textnormal{\textit{//}}}@ { s = std::move(x.s); return *this; } + ~C() { } +}; +\end{codeblock} \end{example} -\rSec1[basic.types]{Types}% +\pnum +\begin{note} +A class name can also be implicitly declared by an +\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}. +\end{note} -\rSec2[basic.types.general]{General}% -\indextext{type|(} +\pnum +\indextext{type!incomplete}% +In the definition of an object, +the type of that object shall not be +an incomplete type\iref{term.incomplete.type}, +an abstract class type\iref{class.abstract}, or +a (possibly multidimensional) array thereof. + +\rSec1[basic.scope]{Scope}% +\indextext{scope|(} + +\rSec2[basic.scope.scope]{General} + +\pnum +The declarations in a program appear in a number of \defnx{scopes}{scope} +that are in general discontiguous. +The \defnadj{global}{scope} contains the entire program; +every other scope $S$ is introduced by a +declaration, +\grammarterm{parameter-declaration-clause}, +\grammarterm{statement}, or \grammarterm{handler} +(as described in the following subclauses of \ref{basic.scope}) +appearing in another scope which thereby contains $S$. +An \defnadj{enclosing}{scope} at a program point is any scope that contains it; +the smallest such scope is said to be the \defnadj{immediate}{scope} +at that point. +A scope \defnx{intervenes}{scope!intervene} +between a program point $P$ and a scope $S$ +(that does not contain $P$) if it is or contains $S$ but does not contain $P$. \pnum +Unless otherwise specified: +\begin{itemize} +\item +The smallest scope that contains a scope $S$ is +the \defnadj{parent}{scope} of $S$. +\item +No two declarations (re)introduce the same entity. +\item +A declaration \defnx{inhabits}{scope!inhabit} +the immediate scope at its locus\iref{basic.scope.pdecl}. +\item +A declaration's \defnadj{target}{scope} is the scope it inhabits. +\item +Any names (re)introduced by a declaration are \defnx{bound}{name!bound} to it +in its target scope. +\end{itemize} +An entity \defnx{belongs}{entity!belong} to a scope $S$ +if $S$ is the target scope of a declaration of the entity. \begin{note} -\ref{basic.types} and the subclauses thereof -impose requirements on implementations regarding the representation -of types. -There are two kinds of types: fundamental types and compound types. -Types describe objects\iref{intro.object}, -references\iref{dcl.ref}, -or functions\iref{dcl.fct}. +Special cases include that: +\begin{itemize} +\item +Template parameter scopes are parents +only to other template parameter scopes\iref{basic.scope.temp}. +\item +Corresponding declarations with appropriate linkage +declare the same entity\iref{basic.link}. +\item +The declaration in a \grammarterm{template-declaration} +inhabits the same scope as the \grammarterm{template-declaration}. +\item +Friend declarations and +declarations of template specializations do not bind names\iref{dcl.meaning}; +those with qualified names target a specified scope, and +other friend declarations and +certain \grammarterm{elaborated-type-specifier}s\iref{dcl.type.elab} +target a larger enclosing scope. +\item +Block-scope extern declarations target a larger enclosing scope +but bind a name in their immediate scope. +\item +The names of unscoped enumerators are bound +in the two innermost enclosing scopes\iref{dcl.enum}. +\item +A class's name is also bound in its own scope\iref{class.pre}. +\item +The names of the members of an anonymous union are bound in +the union's parent scope\iref{class.union.anon}. +\end{itemize} \end{note} \pnum -\indextext{object!byte copying and|(}% -\indextext{type!trivially copyable}% -For any object (other than a potentially-overlapping subobject) of trivially copyable type -\tcode{T}, whether or not the object holds a valid value of type -\tcode{T}, the underlying bytes\iref{intro.memory} making up the -object can be copied into an array of -\keyword{char}, -\tcode{\keyword{unsigned} \keyword{char}}, or -\tcode{std::byte}\iref{cstddef.syn}. +Two non-static member functions have +\defnadjx{corresponding}{object parameters}{object parameter} if +\begin{itemize} +\item +exactly one is an implicit object member function +with no \grammarterm{ref-qualifier} and +the types of their object parameters\iref{dcl.fct}, +after removing references, +are the same, or +\item +their object parameters have the same type. +\end{itemize} +\indextext{template!function!corresponding object parameter}% +Two non-static member function templates have +\defnadjx{corresponding}{object parameters}{object parameter} if +\begin{itemize} +\item +exactly one is an implicit object member function +with no \grammarterm{ref-qualifier} and +the types of their object parameters, +after removing any references, +are equivalent, or +\item +the types of their object parameters are equivalent. +\end{itemize} +\indextext{template!function!corresponding signature}% +Two function templates have +\defnadjx{corresponding}{signatures}{signature} if +their \grammarterm{template-parameter-list}{s} +have the same length, +their corresponding \grammarterm{template-parameter}{s} are equivalent, +they have equivalent non-object-parameter-type-lists and return types (if any), and, +if both are non-static members, they have corresponding object parameters. + +\pnum +Two declarations \defn{correspond} +if they (re)introduce the same name, +both declare constructors, or +both declare destructors, +unless +\begin{itemize} +\item +either is a \grammarterm{using-declarator}, or +\item +one declares a type (not a \grammarterm{typedef-name}) and the other declares a +variable, +non-static data member other than of an anonymous union\iref{class.union.anon}, +enumerator, +function, or +function template, or +\item +each declares a function or function template +and they do not declare corresponding overloads. +\end{itemize} +Two function or function template declarations declare +\defn{corresponding overloads} if +\begin{itemize} +\item +both declare functions with the same non-object-parameter-type-list, \begin{footnote} -By using, for example, the library -functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. +An implicit object parameter\iref{over.match.funcs} +is not part of the parameter-type-list. \end{footnote} -If the content of that array -is copied back into the object, the object shall -subsequently hold its original value. +equivalent\iref{temp.over.link} trailing \grammarterm{requires-clause}s +(if any, except as specified in \ref{temp.friend}), and, +if both are non-static members, +they have corresponding object parameters, or +\item +both declare function templates with corresponding signatures and equivalent +\grammarterm{template-head}s and +trailing \grammarterm{requires-clause}s (if any). +\end{itemize} +\begin{note} +Declarations can correspond even if neither binds a name. \begin{example} \begin{codeblock} -constexpr std::size_t N = sizeof(T); -char buf[N]; -T obj; // \tcode{obj} initialized to its original value -std::memcpy(buf, &obj, N); // between these two calls to \tcode{std::memcpy}, \tcode{obj} might be modified -std::memcpy(&obj, buf, N); // at this point, each subobject of \tcode{obj} of scalar type holds its original value +struct A { + friend void f(); // \#1 +}; +struct B { + friend void f() {} // corresponds to, and defines, \#1 +}; \end{codeblock} \end{example} - -\pnum -For two distinct objects \tcode{obj1} and \tcode{obj2} -of trivially copyable type \tcode{T}, -where neither \tcode{obj1} nor \tcode{obj2} is a potentially-overlapping subobject, -if the underlying bytes\iref{intro.memory} making up -\tcode{obj1} are copied into \tcode{obj2}, -\begin{footnote} -By using, for example, -the library functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. -\end{footnote} - \tcode{obj2} shall subsequently hold the same value as -\tcode{obj1}. +\end{note} \begin{example} \begin{codeblock} -T* t1p; -T* t2p; - // provided that \tcode{t2p} points to an initialized object ... -std::memcpy(t1p, t2p, sizeof(T)); - // at this point, every subobject of trivially copyable type in \tcode{*t1p} contains - // the same value as the corresponding subobject in \tcode{*t2p} +typedef int Int; +enum E : int { a }; +void f(int); // \#1 +void f(Int) {} // defines \#1 +void f(E) {} // OK, another overload + +struct X { + static void f(); + void f() const; // error: redeclaration + void g(); + void g() const; // OK + void g() &; // error: redeclaration + + void h(this X&, int); + void h(int) &&; // OK, another overload + void j(this const X&); + void j() const &; // error: redeclaration + void k(); + void k(this X&); // error: redeclaration +}; \end{codeblock} \end{example} -\indextext{object!byte copying and|)} \pnum -\label{term.object.representation}% -The \defnx{object representation}{representation!object} -of a complete object type \tcode{T} is the -sequence of \placeholder{N} \tcode{\keyword{unsigned} \keyword{char}} objects taken up -by a non-bit-field complete object of type \tcode{T}, -where \placeholder{N} equals -\tcode{\keyword{sizeof}(T)}. -The \defnx{value representation}{representation!value} -of a type \tcode{T} is the set of bits -in the object representation of \tcode{T} -that participate in representing a value of type \tcode{T}. -The object and value representation of -a non-bit-field complete object of type \tcode{T} are -the bytes and bits, respectively, of -the object corresponding to the object and value representation of its type. -The object representation of a bit-field object is -the sequence of \placeholder{N} bits taken up by the object, -where \placeholder{N} is the width of the bit-field\iref{class.bit}. -The value representation of a bit-field object is -the set of bits in the object representation that -participate in representing its value. -\label{term.padding.bits}% -Bits in the object representation of a type or object that are -not part of the value representation -are \defn{padding bits}. -For trivially copyable types, the value representation is -a set of bits in the object representation that determines a -\defn{value}, which is one discrete element of an -\impldef{values of a trivially copyable type} set of values. -\begin{footnote} -The intent is that the memory model of \Cpp{} is compatible -with that of the C programming language. -\end{footnote} +A declaration is \defnx{name-independent}{declaration!name-independent} +if its name is \tcode{_} (\unicode{005f}{low line}) and it declares +\begin{itemize} +\item +a variable with automatic storage duration, +\item +a structured binding +%FIXME: "and" is strange below; maybe reword to something like: +%FIXME: "that has no \grammarterm{storage-class-specifier} and +%FIXME: that is not inhabiting a namespace scope," +with no \grammarterm{storage-class-specifier} and +not inhabiting a namespace scope, +\item +the variable introduced by an \grammarterm{init-capture}, or +\item +%FIXME: "of" is strange below; remove it? +a non-static data member of other than an anonymous union. +\end{itemize} + +\recommended +Implementations should not emit a warning +that a name-independent declaration is used or unused. \pnum -\indextext{type!incompletely-defined object}% -A class that has been declared but not defined, an enumeration type in certain -contexts\iref{dcl.enum}, or an array of unknown -bound or of incomplete element type, is an -\defnadj{incompletely-defined}{object type}. -\begin{footnote} -The size and layout of an instance of an incompletely-defined -object type is unknown. -\end{footnote} -\label{term.incomplete.type}% -Incompletely-defined object types and \cv{}~\keyword{void} are -\defnadjx{incomplete}{types}{type}\iref{basic.fundamental}. +\indextext{declaration!potentially conflict}% +Two declarations \defn{potentially conflict} +if they correspond and +cause their shared name to denote different entities\iref{basic.link}. +The program is ill-formed +if, in any scope, a name is bound to two declarations $A$ and $B$ +that potentially conflict and $A$ precedes $B$\iref{basic.lookup}, +unless $B$ is name-independent. \begin{note} -Objects cannot be defined to have an incomplete type\iref{basic.def}. +An \grammarterm{id-expression} that names a unique name-independent declaration +is usable until an additional declaration of the same name +is introduced in the same scope\iref{basic.lookup.general}. \end{note} - -\pnum -A class type (such as ``\tcode{\keyword{class} X}'') can be incomplete at one -point in a translation unit and complete later on; the type -``\tcode{\keyword{class} X}'' is the same type at both points. The declared type -of an array object can be an array of incomplete class type and -therefore incomplete; if the class type is completed later on in the -translation unit, the array type becomes complete; the array type at -those two points is the same type. The declared type of an array object -can be an array of unknown bound and therefore be incomplete at one -point in a translation unit and complete later on; the array types at -those two points (``array of unknown bound of \tcode{T}'' and ``array of -\tcode{N} \tcode{T}'') are different types. \begin{note} -The type of a pointer or reference to array of unknown bound -permanently points to or refers to an incomplete type. -An array of unknown bound named by a \keyword{typedef} declaration -permanently refers to an incomplete type. -In either case, the array type cannot be completed. +Overload resolution can consider potentially conflicting declarations +found in multiple scopes +(e.g., via \grammarterm{using-directive}s or for operator functions), +in which case it is often ambiguous. \end{note} \begin{example} -\indextext{type!example of incomplete}% \begin{codeblock} -class X; // \tcode{X} is an incomplete type -extern X* xp; // \tcode{xp} is a pointer to an incomplete type -extern int arr[]; // the type of arr is incomplete -typedef int UNKA[]; // \tcode{UNKA} is an incomplete type -UNKA* arrp; // \tcode{arrp} is a pointer to an incomplete type -UNKA** arrpp; - -void foo() { - xp++; // error: \tcode{X} is incomplete - arrp++; // error: incomplete type - arrpp++; // OK, sizeof \tcode{UNKA*} is known +void f() { + int x,y; + void x(); // error: different entity for \tcode{x} + int y; // error: redefinition } +enum { f }; // error: different entity for \tcode{::f} +namespace A {} +namespace B = A; +namespace B = A; // OK, no effect +namespace B = B; // OK, no effect +namespace A = B; // OK, no effect +namespace B {} // error: different entity for \tcode{B} -struct X { int i; }; // now \tcode{X} is a complete type -int arr[10]; // now the type of \tcode{arr} is complete - -X x; -void bar() { - xp = &x; // OK; type is ``pointer to \tcode{X}'' - arrp = &arr; // OK; qualification conversion\iref{conv.qual} - xp++; // OK, \tcode{X} is complete - arrp++; // error: \tcode{UNKA} can't be completed +void g() { + int _; + _ = 0; // OK + int _; // OK, name-independent declaration + _ = 0; // error: two non-function declarations in the lookup set +} +void h () { + int _; // \#1 + _ ++; // OK + static int _; // error: conflicts with \#1 because static variables are not name-independent } \end{codeblock} \end{example} \pnum -\begin{note} -The rules for declarations and expressions describe in which -contexts incomplete types are prohibited. -\end{note} - -\pnum -\label{term.object.type}% -An \defn{object type} is a (possibly cv-qualified) type that is not -a function type, not a reference type, and not \cv{}~\keyword{void}. - -\pnum -\indextext{class!trivial}% -\indextext{class!trivially copyable}% -\indextext{class!standard-layout}% -\label{term.scalar.type}% -Arithmetic types\iref{basic.fundamental}, enumeration types, -pointer types, pointer-to-member types\iref{basic.compound}, -\tcode{std::nullptr_t}, -and -cv-qualified\iref{basic.type.qualifier} versions of these -types are collectively called -\defnadjx{scalar}{types}{type}. -\label{term.trivially.copyable.type}% -Scalar types, trivially copyable class types\iref{class.prop}, -arrays of such types, and cv-qualified versions of these -types are collectively called \defnadjx{trivially copyable}{types}{type}. -\label{term.trivial.type}% -Scalar types, trivial class types\iref{class.prop}, -arrays of such types, and cv-qualified versions of these -types are collectively called -\defnadjx{trivial}{types}{type}. -\label{term.standard.layout.type}% -Scalar types, standard-layout class -types\iref{class.prop}, arrays of such types, and -cv-qualified versions of these types -are collectively called \defnadjx{standard-layout}{types}{type}. -\label{term.implicit.lifetime.type}% -Scalar types, implicit-lifetime class types\iref{class.prop}, -array types, and cv-qualified versions of these types -are collectively called \defnadjx{implicit-lifetime}{types}{type}. +\indextext{declaration!nominable}% +A declaration is \defn{nominable} +in a class, class template, or namespace $E$ at a point $P$ if +it precedes $P$, +it does not inhabit a block scope, and +its target scope is the scope associated with $E$ or, +if $E$ is a namespace, +any element of the inline namespace set of $E$\iref{namespace.def}. +\begin{example} +\begin{codeblock} +namespace A { + void f() {void g();} + inline namespace B { + struct S { + friend void h(); + static int i; + }; + } +} +\end{codeblock} +At the end of this example, +the declarations of \tcode{f}, \tcode{B}, \tcode{S}, and \tcode{h} +are nominable in \tcode{A}, but those of \tcode{g} and \tcode{i} are not. +\end{example} \pnum -\label{term.literal.type}% -A type is a \defnadj{literal}{type} if it is: -\begin{itemize} -\item \cv{}~\keyword{void}; or -\item a scalar type; or -\item a reference type; or -\item an array of literal type; or -\item a possibly cv-qualified class type\iref{class} that -has all of the following properties: -\begin{itemize} -\item it has a constexpr destructor\iref{dcl.constexpr}, -\item all of its non-static non-variant data members and base classes are of non-volatile literal types, and -\item it -\begin{itemize} -\item is a closure type\iref{expr.prim.lambda.closure}, -\item is an aggregate union type that has either -no variant members or -at least one variant member of non-volatile literal type, -\item is a non-union aggregate type for which -each of its anonymous union members -satisfies the above requirements for an aggregate union type, or -\item has at least one constexpr constructor or constructor template -(possibly inherited\iref{namespace.udecl} from a base class) -that is not a copy or move constructor. -\end{itemize} -\end{itemize} -\end{itemize} -\begin{note} -A literal type is one for which -it might be possible to create an object -within a constant expression. -It is not a guarantee that it is possible to create such an object, -nor is it a guarantee that any object of that type -will be usable in a constant expression. -\end{note} +When instantiating a templated entity\iref{temp.pre}, +any scope $S$ introduced by any part of the template definition is considered +to be introduced by the instantiated entity and +to contain the instantiations of any declarations that inhabit $S$. -\pnum -\label{term.layout.compatible.type}% -Two types \cvqual{cv1} \tcode{T1} and \cvqual{cv2} \tcode{T2} are -\defnadjx{layout-compatible}{types}{type} -if \tcode{T1} and \tcode{T2} are the same type, -layout-compatible enumerations\iref{dcl.enum}, or -layout-compatible standard-layout class types\iref{class.mem}. +\rSec2[basic.scope.pdecl]{Point of declaration} -\rSec2[basic.fundamental]{Fundamental types} +\indextext{declaration!point of|see{locus}}% +\indextext{scope!declarations and|see{locus}}% +\indextext{locus|(}% \pnum -\indextext{type!implementation-defined \tcode{sizeof}}% -There are five \defnadjx{standard signed integer}{types}{type}: -\indextext{type!\idxcode{signed char}}% -\indextext{type!\idxcode{short}}% -\indextext{type!\idxcode{int}}% -\indextext{type!\idxcode{long}}% -\indextext{type!\idxcode{long long}}% -``\tcode{\keyword{signed} \keyword{char}}'', ``\tcode{\keyword{short} \keyword{int}}'', ``\keyword{int}'', -``\tcode{\keyword{long} \keyword{int}}'', and ``\tcode{\keyword{long} \keyword{long} \keyword{int}}''. In -this list, each type provides at least as much storage as those -preceding it in the list. -There may also be \impldef{extended signed integer types} -\defnadjx{extended signed integer}{types}{type}. -The standard and extended signed integer types are collectively called -\defnadjx{signed integer}{types}{type}. -The range of representable values for a signed integer type is -$-2^{N-1}$ to $2^{N-1}-1$ (inclusive), -where \placeholder{N} is called the \defn{width} of the type. -\indextext{integral type!implementation-defined \tcode{sizeof}}% -\begin{note} -Plain \tcode{int}s are intended to have -the natural width suggested by the architecture of the execution environment; -the other signed integer types are provided to meet special needs. -\end{note} +\indextext{declaration!locus|see{locus}}% +The \defn{locus} of a declaration\iref{basic.link} that is a declarator +is immediately after the complete declarator\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +unsigned char x = 12; +{ unsigned char x = x; } +\end{codeblock} +Here, the initialization of the second \tcode{x} has undefined behavior, +because the initializer accesses the second \tcode{x} +outside its lifetime\iref{basic.life}. +\end{example} \pnum -\indextext{type!\idxcode{unsigned}}% -For each of the standard signed integer types, -there exists a corresponding (but different) -\defnadj{standard unsigned integer}{type}: -\indextext{type!\idxcode{unsigned char}}% -\indextext{type!\idxcode{unsigned short}}% -\indextext{type!\idxcode{unsigned int}}% -\indextext{type!\idxcode{unsigned long}}% -\indextext{type!\idxcode{unsigned long long}}% -``\tcode{\keyword{unsigned} \keyword{char}}'', ``\tcode{\keyword{unsigned} \keyword{short} \keyword{int}}'', -``\tcode{\keyword{unsigned} \keyword{int}}'', ``\tcode{\keyword{unsigned} \keyword{long} \keyword{int}}'', and -``\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}''. -Likewise, for each of the extended signed integer types, -there exists a corresponding \defnadj{extended unsigned integer}{type}. -The standard and extended unsigned integer types -are collectively called \defnadjx{unsigned integer}{types}{type}. -An unsigned integer type has the same width \placeholder{N} -as the corresponding signed integer type. -\indextext{arithmetic!\idxcode{unsigned}}% -The range of representable values for the unsigned type is -$0$ to $2^N-1$ (inclusive); -arithmetic for the unsigned type is performed modulo $2^N$. \begin{note} -Unsigned arithmetic does not overflow. -Overflow for signed arithmetic yields undefined behavior\iref{expr.pre}. +\indextext{name hiding}% +A name from an outer scope remains visible up to +the locus of the declaration that hides it. +\begin{example} +\begin{codeblock} +const int i = 2; +{ int i[i]; } +\end{codeblock} +declares a block-scope array of two integers. +\end{example} \end{note} \pnum -\indextext{signed integer representation!two's complement}% -An unsigned integer type has the same -object representation, -value representation, and -alignment requirements\iref{basic.align} -as the corresponding signed integer type. -For each value $x$ of a signed integer type, -the value of the corresponding unsigned integer type -congruent to $x$ modulo $2^N$ has the same value -of corresponding bits in its value representation. -\begin{footnote} -This -is also known as two's complement representation. -\end{footnote} +The locus of a \grammarterm{class-specifier} is immediately after +the \grammarterm{identifier} or \grammarterm{simple-template-id} (if any) +in its \grammarterm{class-head}\iref{class.pre}. +The locus of an \grammarterm{enum-specifier} +is immediately after +its \grammarterm{enum-head}; +the locus of an \grammarterm{opaque-enum-declaration} +is immediately after it\iref{dcl.enum}. +%FIXME: What's "it" below? What's "it" above? +The locus of an \grammarterm{alias-declaration} is immediately after it. + +\pnum +The locus of a \grammarterm{using-declarator} +that does not name a constructor +is immediately after the \grammarterm{using-declarator}\iref{namespace.udecl}. + +\pnum +The locus of an \grammarterm{enumerator-definition} is immediately after it. \begin{example} -The value $-1$ of a signed integer type has the same representation as -the largest value of the corresponding unsigned type. +\begin{codeblock} +const int x = 12; +{ enum { x = x }; } +\end{codeblock} +Here, the enumerator \tcode{x} is initialized with the value of the +constant \tcode{x}, namely 12. \end{example} -\begin{floattable}{Minimum width}{basic.fundamental.width}{lc} -\topline -\lhdr{Type} & \rhdr{Minimum width $N$} \\ -\capsep -\tcode{\keyword{signed} \keyword{char}} & 8 \\ -\tcode{\keyword{short} \keyword{int}} & 16 \\ -\keyword{int} & 16 \\ -\tcode{\keyword{long} \keyword{int}} & 32 \\ -\tcode{\keyword{long} \keyword{long} \keyword{int}} & 64 \\ -\end{floattable} - \pnum -The width of each standard signed integer type -shall not be less than the values specified in \tref{basic.fundamental.width}. -The value representation of a signed or unsigned integer type -comprises $N$ bits, where N is the respective width. -Each set of values for any padding bits\iref{basic.types.general} -in the object representation are -alternative representations of the value specified by the value representation. -\begin{note} -Padding bits have unspecified value, but cannot cause traps. -In contrast, see \IsoC{} 6.2.6.2. -\end{note} \begin{note} -The signed and unsigned integer types satisfy -the constraints given in \IsoC{} 5.2.4.2.1. +\indextext{type!incomplete}% +After the declaration of a class member, +the member name can be found in the scope of its class +even if the class is an incomplete class. +\begin{example} +\begin{codeblock} +struct X { + enum E { z = 16 }; + int b[X::z]; // OK +}; +\end{codeblock} +\end{example} \end{note} -Except as specified above, -the width of a signed or unsigned integer type is -\impldef{width of integral type}. \pnum -Each value $x$ of an unsigned integer type with width $N$ has -a unique representation $x = x_0 2^0 + x_1 2^1 + \ldots + x_{N-1} 2^{N-1}$, -where each coefficient $x_i$ is either 0 or 1; -this is called the \defn{base-2 representation} of $x$. -The base-2 representation of a value of signed integer type is -the base-2 representation of the congruent value -of the corresponding unsigned integer type. -The standard signed integer types and standard unsigned integer types -are collectively called the \defnadjx{standard integer}{types}{type}, and the extended -signed integer types and extended -unsigned integer types are collectively called the -\defnadjx{extended integer}{types}{type}. +The locus of an \grammarterm{elaborated-type-specifier} +that is a declaration\iref{dcl.type.elab} is immediately after it. \pnum -A fundamental type specified to have -a signed or unsigned integer type as its \defnadj{underlying}{type} has -the same object representation, -value representation, -alignment requirements\iref{basic.align}, and -range of representable values as the underlying type. -Further, each value has the same representation in both types. +The locus of an injected-class-name declaration\iref{class.pre} +is immediately following the opening brace of the class definition. \pnum -\indextext{type!\idxcode{char}}% -\indextext{type!character}% -\indextext{\idxcode{char}!implementation-defined sign of}% -\indextext{type!\idxcode{signed char}}% -\indextext{character!\idxcode{signed}}% -\indextext{type!\idxcode{unsigned char}}% -Type \keyword{char} is a distinct type -that has an \impldef{underlying type of \tcode{char}} choice of -``\tcode{\keyword{signed} \keyword{char}}'' or ``\tcode{\keyword{unsigned} \keyword{char}}'' as its underlying type. -The three types \keyword{char}, \tcode{\keyword{signed} \keyword{char}}, and \tcode{\keyword{unsigned} \keyword{char}} -are collectively called -\defnadjx{ordinary character}{types}{type}. -The ordinary character types and \keyword{char8_t} -are collectively called \defnadjx{narrow character}{types}{type}. -For narrow character types, -each possible bit pattern of the object representation represents -a distinct value. -\begin{note} -This requirement does not hold for other types. -\end{note} -\begin{note} -A bit-field of narrow character type whose width is larger than -the width of that type has padding bits; see \ref{basic.types.general}. -\end{note} +The locus of the implicit declaration of +a function-local predefined variable\iref{dcl.fct.def.general} +is immediately before +the \grammarterm{function-body} of its function's definition. \pnum -\indextext{\idxcode{wchar_t}|see{type, \tcode{wchar_t}}}% -\indextext{type!\idxcode{wchar_t}}% -\indextext{type!underlying!\idxcode{wchar_t}}% -Type \keyword{wchar_t} is a distinct type that has -an \impldef{underlying type of \tcode{wchar_t}} -signed or unsigned integer type as its underlying type. +The locus of the declaration of a structured binding\iref{dcl.struct.bind} +is immediately after +the \grammarterm{identifier-list} of the structured binding declaration. \pnum -\indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% -\indextext{type!\idxcode{char8_t}}% -\indextext{type!underlying!\idxcode{char8_t}}% -Type \keyword{char8_t} denotes a distinct type -whose underlying type is \tcode{\keyword{unsigned} \keyword{char}}. -\indextext{\idxcode{char16_t}|see{type, \tcode{char16_t}}}% -\indextext{\idxcode{char32_t}|see{type, \tcode{char32_t}}}% -\indextext{type!\idxcode{char16_t}}% -\indextext{type!\idxcode{char32_t}}% -\indextext{type!underlying!\idxcode{char16_t}}% -\indextext{type!underlying!\idxcode{char32_t}}% -Types \keyword{char16_t} and \keyword{char32_t} denote distinct types -whose underlying types are \tcode{uint_least16_t} and \tcode{uint_least32_t}, -respectively, in \libheaderref{cstdint}. +The locus of a \grammarterm{for-range-declaration} +of a range-based \keyword{for} statement\iref{stmt.ranged} +is immediately after the \grammarterm{for-range-initializer}. \pnum -\indextext{Boolean type}% -\indextext{type!Boolean}% -Type \tcode{bool} is a distinct type that has -the same object representation, -value representation, and -alignment requirements as -an \impldef{underlying type of \tcode{bool}} unsigned integer type. -The values of type \keyword{bool} are -\keyword{true} and \keyword{false}. +The locus of a \grammarterm{template-parameter} is immediately after it. +\begin{example} +\begin{codeblock} +typedef unsigned char T; +template struct A { }; +\end{codeblock} +\end{example} + +\pnum +The locus of a \grammarterm{concept-definition} +is immediately after its \grammarterm{concept-name}\iref{temp.concept}. \begin{note} -There are no \keyword{signed}, \keyword{unsigned}, -\keyword{short}, or \tcode{\keyword{long} \keyword{bool}} types or values. +The \grammarterm{constraint-expression} cannot use +the \grammarterm{concept-name}. \end{note} \pnum -\indextext{type!integral}% -The types \keyword{char}, \keyword{wchar_t}, -\keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} -are collectively called \defnadjx{character}{types}{type}. -The character types, \keyword{bool}, -the signed and unsigned integer types, -and cv-qualified versions\iref{basic.type.qualifier} thereof, -are collectively termed -\defnx{integral types}{integral type}. -A synonym for integral type is \defn{integer type}. +The locus of a \grammarterm{namespace-definition} +with an \grammarterm{identifier} +is immediately after the \grammarterm{identifier}. \begin{note} -Enumerations\iref{dcl.enum} are not integral; -however, unscoped enumerations can be promoted to integral types -as specified in \ref{conv.prom}. +An identifier is invented +for an \grammarterm{unnamed-namespace-definition}\iref{namespace.unnamed}. \end{note} \pnum -\indextext{floating-point type|see{type, floating-point}}% -The three distinct types -\indextext{type!\idxcode{float}}% -\keyword{float}, -\indextext{type!\idxcode{double}}% -\keyword{double}, -and -\indextext{type!\idxcode{long double}}% -\tcode{\keyword{long} \keyword{double}} -can represent floating-point numbers. -The type \keyword{double} provides at least as much -precision as \keyword{float}, and the type \tcode{\keyword{long} \keyword{double}} provides at -least as much precision as \keyword{double}. The set of values of the type -\keyword{float} is a subset of the set of values of the type -\keyword{double}; the set of values of the type \keyword{double} is a subset -of the set of values of the type \tcode{\keyword{long} \keyword{double}}. -The types -\keyword{float}, \keyword{double}, and \tcode{\keyword{long} \keyword{double}}, -and cv-qualified versions\iref{basic.type.qualifier} thereof, -are collectively termed -\defnx{standard floating-point types}{type!floating-point!standard}. -An implementation may also provide additional types -that represent floating-point values and define them (and cv-qualified versions thereof) to be -\defnx{extended floating-point types}{type!floating-point!extended}. -The standard and extended floating-point types -are collectively termed \defnx{floating-point types}{type!floating-point}. \begin{note} -Any additional implementation-specific types representing floating-point values -that are not defined by the implementation to be extended floating-point types -are not considered to be floating-point types, and -this document imposes no requirements on them or -their interactions with floating-point types. +Friend declarations can introduce functions or classes +that belong to the nearest enclosing namespace or block scope, +but they do not bind names anywhere\iref{class.friend}. +Function declarations at block scope and +variable declarations with the \keyword{extern} specifier at block scope +declare entities +that belong to the nearest enclosing namespace, +but they do not bind names in it. \end{note} -Except as specified in \ref{basic.extended.fp}, -the object and value representations and accuracy of operations -of floating-point types are \impldef{representation of floating-point types}. \pnum -The minimum range of representable values for a floating-point type is -the most negative finite floating-point number representable -in that type through -the most positive finite floating-point number representable in that type. -In addition, if negative infinity is representable in a type, -the range of that type is extended to all negative real numbers; -likewise, if positive infinity is representable in a type, -the range of that type is extended to all positive real numbers. \begin{note} -Since negative and positive infinity are representable -in \IsoFloatUndated{} formats, -all real numbers lie within the range of representable values of -a floating-point type adhering to \IsoFloatUndated{}. +For point of instantiation of a template, see~\ref{temp.point}. \end{note} +\indextext{locus|)} + +\rSec2[basic.scope.block]{Block scope} + +\indextext{local scope|see{scope, block}}% \pnum -Integral and floating-point types are collectively -termed \defnx{arithmetic types}{type!arithmetic}. +Each +\begin{itemize} +\item +selection or iteration statement\iref{stmt.select,stmt.iter}, +\item +substatement of such a statement, +\item +\indextext{scope!\idxgram{handler}}% +\grammarterm{handler}\iref{except.pre}, or +\item +compound statement\iref{stmt.block} +that is not the \grammarterm{compound-statement} of a \grammarterm{handler} +\end{itemize} +introduces a \defnadj{block}{scope} +that includes that statement or \grammarterm{handler}. \begin{note} -Properties of the arithmetic types, -such as their minimum and maximum representable value, -can be queried using the facilities in the standard library headers -\libheaderref{limits}, -\libheaderref{climits}, and -\libheaderref{cfloat}. +A substatement that is also a block has only one scope. \end{note} +A variable that belongs to a block scope is a \defn{block variable}. +\begin{example} +\begin{codeblock} +int i = 42; +int a[10]; + +for (int i = 0; i < 10; i++) + a[i] = i; + +int j = i; // \tcode{j = 42} +\end{codeblock} +\end{example} \pnum -\indextext{type!\idxcode{void}}% -A type \cv{}~\keyword{void} -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 +If a declaration +that is not a name-independent declaration and +that binds a name in the block scope $S$ of a \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 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}, -\item the operand of a \keyword{decltype} specifier\iref{dcl.type.decltype}, or -\item the operand of an explicit conversion to type -\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. +\item +\grammarterm{compound-statement} of a \grammarterm{lambda-expression}, +\grammarterm{function-body}, or \grammarterm{function-try-block}, +\item +substatement of a selection or iteration statement +that is not itself a selection or iteration statement, or +\item +\grammarterm{handler} of a \grammarterm{function-try-block} \end{itemize} +potentially conflicts with a declaration +whose target scope is the parent scope of $S$, +the program is ill-formed. +\begin{example} +\begin{codeblock} +if (int x = f()) { + int x; // error: redeclaration of \tcode{x} +} +else { + int x; // error: redeclaration of \tcode{x} +} +\end{codeblock} +\end{example} -\pnum -The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. -A value of type \tcode{std::nullptr_t} is a null pointer -constant\iref{conv.ptr}. Such values participate in the pointer and the -pointer-to-member conversions\iref{conv.ptr,conv.mem}. -\tcode{\keyword{sizeof}(std::nullptr_t)} shall be equal to \tcode{\keyword{sizeof}(\keyword{void}*)}. +\rSec2[basic.scope.param]{Function parameter scope} + +\indextext{scope!function prototype|see{scope, function parameter}}% +\indextext{parameter!scope of}% \pnum -\indextext{type!fundamental}% -The types described in this subclause -are called \defnx{fundamental types}{fundamental type}. +A \grammarterm{parameter-declaration-clause} $P$ introduces +a \defnadj{function parameter}{scope} that includes $P$. \begin{note} -Even if the implementation defines two or more fundamental types to have the -same value representation, they are nevertheless different types. +A function parameter cannot be used for its value +within the \grammarterm{parameter-declaration-clause}\iref{dcl.fct.default}. \end{note} +\begin{itemize} +\item +If $P$ is associated with a \grammarterm{declarator} and +is preceded by a (possibly-parenthesized) \grammarterm{noptr-declarator} of +the form +\grammarterm{declarator-id} \opt{\grammarterm{attribute-specifier-seq}}, +its scope extends to the end of the nearest enclosing +\grammarterm{init-declarator}, +\grammarterm{member-declarator}, +\grammarterm{declarator} of a \grammarterm{parameter-declaration} or +a \grammarterm{nodeclspec-function-declaration}, or +\grammarterm{function-definition}, +but does not include the locus of the associated \grammarterm{declarator}. +\begin{note} +In this case, $P$ declares the parameters of a function +(or a function or template parameter declared with function type). +A member function's parameter scope is nested within its class's scope. +\end{note} +\item +If $P$ is associated with a \grammarterm{lambda-declarator}, +its scope extends to the end of the \grammarterm{compound-statement} +in the \grammarterm{lambda-expression}. +\item +If $P$ is associated with a \grammarterm{requirement-parameter-list}, +its scope extends to the end of the \grammarterm{requirement-body} of the \grammarterm{requires-expression}. +\item +If $P$ is associated with a \grammarterm{deduction-guide}, +its scope extends to the end of the \grammarterm{deduction-guide}. +\end{itemize} -\rSec2[basic.extended.fp]{Optional extended floating-point types} - -\pnum -If the implementation supports an extended floating-point type\iref{basic.fundamental} -whose properties are specified by -the \IsoFloatUndated{} floating-point interchange format binary16, -then the \grammarterm{typedef-name} \tcode{std::float16_t} -is defined in the header \libheaderref{stdfloat} and names such a type, -the macro \mname{STDCPP_FLOAT16_T} is defined\iref{cpp.predefined}, and -the floating-point literal suffixes \tcode{f16} and \tcode{F16} -are supported\iref{lex.fcon}. +\rSec2[basic.scope.lambda]{Lambda scope} -\pnum -If the implementation supports an extended floating-point type -whose properties are specified by -the \IsoFloatUndated{} floating-point interchange format binary32, -then the \grammarterm{typedef-name} \tcode{std::float32_t} -is defined in the header \libheader{stdfloat} and names such a type, -the macro \mname{STDCPP_FLOAT32_T} is defined, and -the floating-point literal suffixes \tcode{f32} and \tcode{F32} are supported. +A \grammarterm{lambda-expression} \tcode{E} introduces a \defnadj{lambda}{scope} +that starts immediately after the \grammarterm{lambda-introducer} of \tcode{E} +and extends to the end of the \grammarterm{compound-statement} of \tcode{E}. -\pnum -If the implementation supports an extended floating-point type -whose properties are specified by -the \IsoFloatUndated{} floating-point interchange format binary64, -then the \grammarterm{typedef-name} \tcode{std::float64_t} -is defined in the header \libheader{stdfloat} and names such a type, -the macro \mname{STDCPP_FLOAT64_T} is defined, and -the floating-point literal suffixes \tcode{f64} and \tcode{F64} are supported. +\rSec2[basic.scope.namespace]{Namespace scope} \pnum -If the implementation supports an extended floating-point type -whose properties are specified by -the \IsoFloatUndated{} floating-point interchange format binary128, -then the \grammarterm{typedef-name} \tcode{std::float128_t} -is defined in the header \libheader{stdfloat} and names such a type, -the macro \mname{STDCPP_FLOAT128_T} is defined, and -the floating-point literal suffixes \tcode{f128} and \tcode{F128} are supported. +Any \grammarterm{namespace-definition} for a namespace $N$ introduces +a \defnadj{namespace}{scope} +that includes the \grammarterm{namespace-body} +for every \grammarterm{namespace-definition} for $N$. +For each non-friend redeclaration or specialization +whose target scope is or is contained by the scope, +the portion after the +\grammarterm{declarator-id}, +\grammarterm{class-head-name}, or +\grammarterm{enum-head-name} +is also included in the scope. +The global scope is +the namespace scope of the global namespace\iref{basic.namespace}. +\begin{example} +\begin{codeblock} +namespace Q { + namespace V { void f(); } + void V::f() { // in the scope of \tcode{V} + void h(); // declares \tcode{Q::V::h} + } +} +\end{codeblock} +\end{example} -\pnum -If the implementation supports an extended floating-point type -with the properties, as specified by \IsoFloatUndated{}, of -radix ($b$) of 2, -storage width in bits ($k$) of 16, -precision in bits ($p$) of 8, -maximum exponent ($emax$) of 127, and -exponent field width in bits ($w$) of 8, then -the \grammarterm{typedef-name} \tcode{std::bfloat16_t} -is defined in the header \libheader{stdfloat} and names such a type, -the macro \mname{STDCPP_BFLOAT16_T} is defined, and -the floating-point literal suffixes \tcode{bf16} and \tcode{BF16} are supported. +\rSec2[basic.scope.class]{Class scope} \pnum +Any declaration of a class or class template $C$ introduces +a \defnadj{class}{scope} +that includes the \grammarterm{member-specification} of +the \grammarterm{class-specifier} for $C$ (if any). +For each non-friend redeclaration or specialization +whose target scope is or is contained by the scope, +the portion after the +\grammarterm{declarator-id}, +\grammarterm{class-head-name}, or +\grammarterm{enum-head-name} is also included in the scope. \begin{note} -A summary of the parameters for each type is given in \tref{basic.extended.fp}. -The precision $p$ includes the implicit 1 bit at the beginning of the significand, -so the storage used for the significand is $p-1$ bits. -\IsoFloatUndated{} does not assign a name for a type -having the parameters specified for \tcode{std::bfloat16_t}. -\end{note} -\begin{floattable} -{Properties of named extended floating-point types}{basic.extended.fp}{llllll} -\topline -\lhdr{Parameter} & \chdr{\tcode{float16_t}} & \chdr{\tcode{float32_t}} & -\chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & -\rhdr{\tcode{bfloat16_t}} \\ -\capsep -\IsoFloatUndated{} name & binary16 & binary32 & binary64 & binary128 & \\ -$k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ -$p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ -$emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ -$w$, exponent field width in bits & 5 & 8 & 11 & 15 & 8 \\ -\end{floattable} +Lookup from a program point +before the \grammarterm{class-specifier} of a class +will find no bindings in the class scope. +\begin{example} +\begin{codeblock} +template +struct B { + D::type x; // \#1 +}; -\pnum -\recommended -Any names that the implementation provides for -the extended floating-point types described in this subsection -that are in addition to the names defined in the \libheader{stdfloat} header -should be chosen to increase compatibility and interoperability -with the interchange types -\tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} -defined in ISO/IEC TS 18661-3 and with future versions of \IsoCUndated{}. +struct A { using type = int; }; +struct C : A, B {}; // error at \#1: \tcode{C::type} not found +\end{codeblock} +\end{example} +\end{note} -\rSec2[basic.compound]{Compound types} +\rSec2[basic.scope.enum]{Enumeration scope}% \pnum -\indextext{type!compound}% -Compound types can be constructed in the following ways: -\begin{itemize} -\item \defnx{arrays}{type!array} of objects of a given type, \ref{dcl.array}; +Any declaration of an enumeration $E$ introduces +an \defnadj{enumeration}{scope} +that includes the \grammarterm{enumerator-list} of +the \grammarterm{enum-specifier} for $E$ (if any). -\item \defnx{functions}{type!function}, which have parameters of given types and return -\keyword{void} or references or objects of a given type, \ref{dcl.fct}; +\rSec2[basic.scope.temp]{Template parameter scope}% -\item \defnx{pointers}{type!pointer} to \cv{}~\keyword{void} or objects or functions (including -static members of classes) of a given type, \ref{dcl.ptr}; +\pnum +Each template \grammarterm{template-parameter} introduces +a \defnadj{template parameter}{scope} +that includes the \grammarterm{template-head} of +the \grammarterm{template-parameter}. -\item -\indextext{reference!lvalue}% -\indextext{reference!rvalue}% -\defnx{references}{reference} to objects or functions of a given -type, \ref{dcl.ref}. There are two types of references: -\begin{itemize} -\item lvalue reference -\item rvalue reference -\end{itemize} +\pnum +Each \grammarterm{template-declaration} $D$ introduces +a template parameter scope +that extends from the beginning of its \grammarterm{template-parameter-list} +to the end of the \grammarterm{template-declaration}. +Any declaration outside the \grammarterm{template-parameter-list} +that would inhabit that scope instead inhabits the same scope as $D$. +The parent scope of any scope $S$ that is not a template parameter scope +is the smallest scope that contains $S$ and is not a template parameter scope. +\begin{note} +Therefore, only template parameters belong to a template parameter scope, and +only template parameter scopes have +a template parameter scope as a parent scope. +\end{note} -\item -\defnx{classes}{class} containing a sequence of objects of various types\iref{class}, -a set of types, enumerations and functions for -manipulating these objects\iref{class.mfct}, and a set of restrictions -on the access to these entities\iref{class.access}; +\indextext{scope|)} -\item -\defnx{unions}{\idxcode{union}}, which are classes capable of containing objects of -different types at different times, \ref{class.union}; +\rSec1[basic.lookup]{Name lookup}% -\item -\defnx{enumerations}{\idxcode{enum}}, -which comprise a set of named constant values, \ref{dcl.enum}; +\indextext{lookup!name|(} -\item -\indextext{member pointer to|see{pointer to member}}% -\defnx{pointers to non-static class members}{pointer to member},% -\begin{footnote} -Static class members are objects or functions, and pointers to them are -ordinary pointers to objects or functions. -\end{footnote} -which identify members of a given -type within objects of a given class, \ref{dcl.mptr}. -Pointers to data members and pointers to member functions are collectively -called \term{pointer-to-member} types. -\end{itemize} +\rSec2[basic.lookup.general]{General}% +\indextext{scope!name lookup and|see{lookup, name}}% \pnum -These methods of constructing types can be applied recursively; -restrictions are mentioned in~\ref{dcl.meaning}. -Constructing a type such that the number of -bytes in its object representation exceeds the maximum value representable in -the type \tcode{std::size_t}\iref{support.types} is ill-formed. +The name lookup rules apply uniformly to all names (including +\grammarterm{typedef-name}{s}\iref{dcl.typedef}, +\grammarterm{namespace-name}{s}\iref{basic.namespace}, and +\grammarterm{class-name}{s}\iref{class.name}) wherever the grammar allows +such names in the context discussed by a particular rule. Name lookup +associates the use of a name with a set of declarations\iref{basic.def} of +that name. +Unless otherwise specified, +the program is ill-formed if no declarations are found. +If the declarations found by name lookup +all denote functions or function templates, +the declarations are said to form an \defn{overload set}. +Otherwise, +if the declarations found by name lookup do not all denote the same entity, +\indextext{lookup!ambiguous}% +they are \defn{ambiguous} and the program is ill-formed. +Overload resolution\iref{over.match,over.over} +takes place after name lookup has succeeded. The access rules\iref{class.access} +are considered only once name lookup and +function overload resolution (if applicable) have succeeded. Only after +name lookup, function overload resolution (if applicable) and access +checking have succeeded +are the semantic properties introduced by the declarations +used in further processing. \pnum -\indextext{terminology!pointer}% -The type of a pointer to \cv{}~\keyword{void} or a pointer to an object type is -called an \defn{object pointer type}. +A program point $P$ is said to follow +any declaration in the same translation unit +whose locus\iref{basic.scope.pdecl} is before $P$. \begin{note} -A pointer to \keyword{void} -does not have a pointer-to-object type, however, because \keyword{void} is not -an object type. +The declaration might appear in a scope that does not contain $P$. \end{note} -The type of a pointer that can designate a function -is called a \defn{function pointer type}. -A pointer to an object of type \tcode{T} is referred to as a ``pointer to -\tcode{T}''. -\begin{example} -A pointer to an object of type \keyword{int} is -referred to as ``pointer to \keyword{int}'' and a pointer to an object of -class \tcode{X} is called a ``pointer to \tcode{X}''. -\end{example} -Except for pointers to static members, text referring to ``pointers'' -does not apply to pointers to members. Pointers to incomplete types are -allowed although there are restrictions on what can be done with -them\iref{basic.types.general}. -\indextext{address}% -Every value of pointer type is one of the following: +\indextext{precede|see{declaration, precede}}% +A declaration $X$ \defnx{precedes}{declaration!precede} +a program point $P$ in a translation unit $L$ +if $P$ follows $X$, $X$ inhabits a class scope and is reachable from $P$, or +else $X$ appears in a translation unit $D$ and \begin{itemize} \item -a \defn{pointer to} an object or function (the pointer is said to \defn{point} to the object or function), or -\item -a \defn{pointer past the end of} an object\iref{expr.add}, or +$P$ follows +a \grammarterm{module-import-declaration} or \grammarterm{module-declaration} +that imports $D$ (directly or indirectly), and \item -\indextext{null pointer value|see{value, null pointer}} -the \defnx{null pointer value}{value!null pointer} for that type, or +$X$ appears after the \grammarterm{module-declaration} in $D$ (if any) and +before the \grammarterm{private-module-fragment} in $D$ (if any), and \item -\indextext{invalid pointer value|see{value, invalid pointer}} -an \defnx{invalid pointer value}{value!invalid pointer}. -\end{itemize} -A value of a -pointer type -that is a pointer to or past the end of an object -\defn{represents the address} of -the first byte in memory\iref{intro.memory} occupied by the object -\begin{footnote} -For an object that is not within its lifetime, -this is the first byte in memory that it will occupy or used to occupy. -\end{footnote} -or the first byte in memory -after the end of the storage occupied by the object, -respectively. +either $X$ is exported or else $D$ and $L$ are part of the same module and +$X$ does not inhabit a namespace with internal linkage or +declare a name with internal linkage. \begin{note} -A pointer past the end of an object\iref{expr.add} -is not considered to point to an unrelated object -of the object's type, -even if the unrelated object is located at that address. +Names declared by a \grammarterm{using-declaration} have no linkage. \end{note} -For purposes of pointer arithmetic\iref{expr.add} -and comparison\iref{expr.rel,expr.eq}, -a pointer past the end of the last element of -an array \tcode{x} of $n$ elements -is considered to be equivalent to -a pointer to a hypothetical array element $n$ of \tcode{x} and -an object of type \tcode{T} that is not an array element -is considered to belong to an array with one element of type \tcode{T}. -The value representation of -pointer types is \impldef{value representation of pointer types}. Pointers to -layout-compatible types shall -have the same value representation and alignment -requirements\iref{basic.align}. +\end{itemize} \begin{note} -Pointers to over-aligned types\iref{basic.align} have no special -representation, but their range of valid values is restricted by the extended -alignment requirement. +A \grammarterm{module-import-declaration} imports both +the named translation unit(s) and +any modules named by exported +\grammarterm{module-import-declaration}{s} within them, +recursively. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module Q; +export int sq(int i) { return i*i; } +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module R; +export import Q; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +import R; +int main() { return sq(9); } // OK, \tcode{sq} from module \tcode{Q} +\end{codeblocktu} +\end{example} \end{note} \pnum -A pointer value $P$ is -\indextext{value!valid in the context of an evaluation}% -\defn{valid in the context of} an evaluation $E$ -if $P$ is a null pointer value, or -if it is a pointer to or past the end of an object $O$ and -$E$ happens before the end of the duration of the region of storage for $O$. -If a pointer value $P$ is used in an evaluation $E$ and -$P$ is not valid in the context of $E$, -then the behavior is undefined if $E$ is -an indirection\iref{expr.unary.op} or -an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation}, -and \impldef{invalid pointer value in the context of an evaluation} otherwise. -\begin{footnote} -Some implementations might define that -copying such a pointer value causes a system-generated runtime fault. -\end{footnote} +\indextext{scope!search!single}% +A \defnadj{single}{search} in a scope $S$ +for a name $N$ from a program point $P$ +finds all declarations that precede $P$ +to which any name that is the same as $N$\iref{basic.link} is bound in $S$. +If any such declaration is a \grammarterm{using-declarator} +whose terminal name\iref{expr.prim.id.unqual} +is not dependent\iref{temp.dep.type}, +it is replaced by the declarations named by +the \grammarterm{using-declarator}\iref{namespace.udecl}. + +\pnum +In certain contexts, only certain kinds of declarations are included. +After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found. \begin{note} -$P$ can be valid in the context of $E$ even -if it points to a type unrelated to that of $O$ or -if $O$ is not within its lifetime, -although further restrictions apply -to such pointer values\iref{basic.life, basic.lval, expr.add}. +A type (but not a \grammarterm{typedef-name} or template) +is therefore hidden by any other entity in its scope. \end{note} +\indextext{type-only!lookup|see{lookup, type-only}}% +However, if a lookup is \defnx{type-only}{lookup!type-only}, +only declarations of +types and templates whose specializations are types are considered; +furthermore, if declarations +of a \grammarterm{typedef-name} and of the type to which it refers are found, +the declaration of the \grammarterm{typedef-name} is discarded +instead of the type declaration. + +\rSec2[class.member.lookup]{Member name lookup}% +\indextext{lookup!member name}% +\indextext{ambiguity!base class member}% +\indextext{ambiguity!member access} \pnum -Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if -\begin{itemize} -\item -they are the same object, or -\item -one is a union object and -the other is a non-static data member of that object\iref{class.union}, or -\item -one is a standard-layout class object and -the other is the first non-static data member of that object or -any base class subobject of that object\iref{class.mem}, or -\item -there exists an object \placeholder{c} such that -\placeholder{a} and \placeholder{c} are pointer-interconvertible, and -\placeholder{c} and \placeholder{b} are pointer-interconvertible. -\end{itemize} -If two objects are pointer-interconvertible, -then they have the same address, -and it is possible to obtain a pointer to one -from a pointer to the other -via a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}. +\indextext{scope!search}% +A \defn{search} in a scope $X$ for a name $M$ from a program point $P$ +is a single search in $X$ for $M$ from $P$ +unless $X$ is the scope of a class or class template $T$, in which case the +following steps define the result of the search. \begin{note} -An array object and its first element are not pointer-interconvertible, -even though they have the same address. +The result differs only +if $M$ is a \grammarterm{conversion-function-id} or +if the single search would find nothing. \end{note} \pnum -A byte of storage \placeholder{b} -is \defnx{reachable through}{storage!reachable through a pointer value} -a pointer value that points to an object \placeholder{x} -if there is an object \placeholder{y}, -pointer-interconvertible with \placeholder{x}, -such that \placeholder{b} is within the storage occupied by -\placeholder{y}, or the immediately-enclosing array object -if \placeholder{y} is an array element. +The \defn{lookup set} for a name $N$ in a class or class template $C$, called $S(N,C)$, +consists of two component sets: +the \term{declaration set}, a set of members named $N$; and +the \term{subobject set}, +a set of subobjects where declarations of these members were found +(possibly via \grammarterm{using-declaration}{s}). +In the declaration set, type declarations (including injected-class-names) +are replaced by the types they designate. $S(N,C)$ is calculated as follows: \pnum -\indextext{pointer|seealso{\tcode{void*}}}% -\indextext{\idxcode{void*}!type}% -A pointer to \cv{}~\keyword{void} -can be used to point to objects of -unknown type. Such a pointer shall be able to hold any object pointer. -An object of type ``pointer to \cv{}~\keyword{void}'' -shall have the same representation and alignment -requirements as an object of type ``pointer to \cv{}~\keyword{char}''. +The declaration set is the result of +a single search in the scope of $C$ for $N$ +from immediately after the \grammarterm{class-specifier} of $C$ +if $P$ is in a complete-class context of $C$ or +from $P$ otherwise. +If the resulting declaration set is not empty, the subobject set +contains $C$ itself, and calculation is complete. -\rSec2[basic.type.qualifier]{CV-qualifiers} +\pnum +Otherwise (i.e., $C$ does not contain a declaration of $N$ +or the resulting declaration set is empty), $S(N,C)$ is initially empty. +Calculate the lookup set for $N$ +in each direct non-dependent\iref{temp.dep.type} base class subobject $B_i$, and +merge each such lookup set $S(N,B_i)$ in turn into $S(N,C)$. +\begin{note} +If $C$ is incomplete, +only base classes whose \grammarterm{base-specifier} appears before $P$ +are considered. +If $C$ is an instantiated class, its base classes are not dependent. +\end{note} \pnum -\indextext{cv-qualifier}% -\indextext{\idxcode{const}}% -\indextext{\idxcode{volatile}}% -Each type other than a function or reference type -is part of a group of four distinct, but related, types: -a \defn{cv-unqualified} version, -a \defn{const-qualified} version, -a \defn{volatile-qualified} version, and -a \defn{const-volatile-qualified} version. -The types in each such group shall have -the same representation and alignment requirements\iref{basic.align}. -\begin{footnote} -The same representation and alignment requirements -are meant to imply interchangeability as -arguments to functions, -return values from functions, and -non-static data members of unions. -\end{footnote} -A function or reference type is always cv-unqualified. +The following steps define the result of merging lookup set $S(N,B_i)$ +into the intermediate $S(N,C)$: + \begin{itemize} -\item A \defnadj{const}{object} is an object of type \tcode{\keyword{const} T} or a - non-mutable subobject of a const object. +\item If each of the subobject members of $S(N,B_i)$ is a base class +subobject of at least one of the subobject members of $S(N,C)$, or if +$S(N,B_i)$ is empty, $S(N,C)$ is unchanged and the merge is complete. +Conversely, if each of the subobject members of $S(N,C)$ is a base class +subobject of at least one of the subobject members of $S(N,B_i)$, or if +$S(N,C)$ is empty, the new $S(N,C)$ is a copy of $S(N,B_i)$. -\item A \defnadj{volatile}{object} is an object of type - \tcode{\keyword{volatile} T} or a subobject of a volatile object. +\item Otherwise, if the declaration sets of $S(N,B_i)$ and $S(N,C)$ +differ, the merge is ambiguous: the new $S(N,C)$ is a lookup set with an +invalid declaration set and the union of the subobject sets. In +subsequent merges, an invalid declaration set is considered different +from any other. -\item A \defnadj{const volatile}{object} is an object of type - \tcode{\keyword{const} \keyword{volatile} T}, a non-mutable subobject of a const volatile object, - a const subobject of a volatile object, or a non-mutable volatile - subobject of a const object. +\item Otherwise, the new $S(N,C)$ is a lookup set with the shared set of +declarations and the union of the subobject sets. \end{itemize} + +\pnum +The result of the search is the declaration set of $S(M,T)$. +If it is an invalid set, the program is ill-formed. +If it differs from the result of a search in $T$ for $M$ +in a complete-class context\iref{class.mem} of $T$, +the program is ill-formed, no diagnostic required. +\begin{example} +\begin{codeblock} +struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} +struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} +struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} +struct D: public virtual C { }; // S(x,D) = S(x,C) +struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} +struct F: public D, public E { }; // S(x,F) = S(x,E) +int main() { + F f; + f.x = 0; // OK, lookup finds \tcode{E::x} +} +\end{codeblock} + +$S(\tcode{x},\tcode{F})$ is unambiguous because the \tcode{A} and \tcode{B} base +class subobjects of \tcode{D} are also base class subobjects of \tcode{E}, so +$S(\tcode{x},\tcode{D})$ is discarded in the first merge step. +\end{example} + +\pnum +If $M$ is a non-dependent \grammarterm{conversion-function-id}, +conversion function templates that are members of $T$ are considered. +For each such template $F$, the lookup set $S(t,T)$ is constructed, +considering a function template declaration to have the name $t$ +only if it corresponds to a declaration of $F$\iref{basic.scope.scope}. +The members of the declaration set of each such lookup set, +which shall not be an invalid set, are included in the result. \begin{note} -The type of an object\iref{intro.object} includes -the \grammarterm{cv-qualifier}s specified in the -\grammarterm{decl-specifier-seq}\iref{dcl.spec}, -\grammarterm{declarator}\iref{dcl.decl}, -\grammarterm{type-id}\iref{dcl.name}, or -\grammarterm{new-type-id}\iref{expr.new} -when the object is created. +Overload resolution will discard those +that cannot convert to the type specified by $M$\iref{temp.over}. \end{note} \pnum -Except for array types, a compound type\iref{basic.compound} is not cv-qualified by the -cv-qualifiers (if any) of the types from which it is compounded. +\begin{note} +A static member, a nested type or an enumerator defined in a base class +\tcode{T} can unambiguously be found even if an object has more than one +base class subobject of type \tcode{T}. Two base class subobjects share +the non-static member subobjects of their common virtual base classes. +\end{note} +\begin{example} +\begin{codeblock} +struct V { + int v; +}; +struct A { + int a; + static int s; + enum { e }; +}; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; + +void f(D* pd) { + pd->v++; // OK, only one \tcode{v} (virtual) + pd->s++; // OK, only one \tcode{s} (static) + int i = pd->e; // OK, only one \tcode{e} (enumerator) + pd->a++; // error: ambiguous: two \tcode{a}{s} in \tcode{D} +} +\end{codeblock} +\end{example} \pnum -\indextext{array!\idxcode{const}}% -An array type whose elements are cv-qualified -is also considered to have the same cv-qualifications -as its elements. \begin{note} -Cv-qualifiers applied to an array -type attach to the underlying element type, so the notation -``\cv{}~\tcode{T}'', where \tcode{T} is an array type, refers to -an array whose elements are so-qualified\iref{dcl.array}. +\indextext{dominance!virtual base class}% +When virtual base classes are used, a hidden declaration can be reached +along a path through the subobject lattice that does not pass through +the hiding declaration. This is not an ambiguity. The identical use with +non-virtual base classes is an ambiguity; in that case there is no +unique instance of the name that hides all the others. \end{note} \begin{example} \begin{codeblock} -typedef char CA[5]; -typedef const char CC; -CC arr1[5] = { 0 }; -const CA arr2 = { 0 }; -\end{codeblock} -The type of both \tcode{arr1} and \tcode{arr2} is ``array of 5 -\tcode{\keyword{const} \keyword{char}}'', and the array type is considered to be -const-qualified. -\end{example} -\indextext{type|)} +struct V { int f(); int x; }; +struct W { int g(); int y; }; +struct B : virtual V, W { + int f(); int x; + int g(); int y; +}; +struct C : virtual V, W { }; -\pnum -\begin{note} -See~\ref{dcl.fct} and~\ref{over.match.funcs} regarding function -types that have \grammarterm{cv-qualifier}{s}. -\end{note} +struct D : B, C { void glorp(); }; +\end{codeblock} -\pnum -There is a partial ordering on cv-qualifiers, so that a type can be -said to be \defn{more cv-qualified} than another. -\tref{basic.type.qualifier.rel} shows the relations that -constitute this ordering. +\begin{importgraphic} +{Name lookup} +{class.lookup} +{figname.pdf} +\end{importgraphic} -\begin{floattable}{Relations on \keyword{const} and \keyword{volatile}}{basic.type.qualifier.rel} -{ccc} -\topline -\cvqual{no cv-qualifier} &<& \keyword{const} \\ -\cvqual{no cv-qualifier} &<& \keyword{volatile} \\ -\cvqual{no cv-qualifier} &<& \tcode{\keyword{const} \keyword{volatile}} \\ -\keyword{const} &<& \tcode{\keyword{const} \keyword{volatile}} \\ -\keyword{volatile} &<& \tcode{\keyword{const} \keyword{volatile}} \\ -\end{floattable} +As illustrated in \fref{class.lookup}, +the names declared in \tcode{V} and the left-hand instance of \tcode{W} +are hidden by those in \tcode{B}, but the names declared in the +right-hand instance of \tcode{W} are not hidden at all. +\begin{codeblock} +void D::glorp() { + x++; // OK, \tcode{B::x} hides \tcode{V::x} + f(); // OK, \tcode{B::f()} hides \tcode{V::f()} + y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} + g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} +} +\end{codeblock} +\end{example} +\indextext{ambiguity!class conversion}% \pnum -In this document, the notation \cv{} (or -\cvqual{cv1}, \cvqual{cv2}, etc.), used in the description of types, -represents an arbitrary set of cv-qualifiers, i.e., one of -\{\keyword{const}\}, \{\keyword{volatile}\}, \{\keyword{const}, -\keyword{volatile}\}, or the empty set. -For a type \cv{}~\tcode{T}, the \defnx{top-level cv-qualifiers}{cv-qualifier!top-level} -of that type are those denoted by \cv. +An explicit or implicit conversion from a pointer to or +an expression designating an object +of a +derived class to a pointer or reference to one of its base classes shall +unambiguously refer to a unique object representing the base class. \begin{example} -The type corresponding to the \grammarterm{type-id} -\tcode{\keyword{const} \keyword{int}\&} -has no top-level cv-qualifiers. -The type corresponding to the \grammarterm{type-id} -\tcode{\keyword{volatile} \keyword{int} * \keyword{const}} -has the top-level cv-qualifier \keyword{const}. -For a class type \tcode{C}, -the type corresponding to the \grammarterm{type-id} -\tcode{\keyword{void} (C::* \keyword{volatile})(\keyword{int}) \keyword{const}} -has the top-level cv-qualifier \keyword{volatile}. -\end{example} +\begin{codeblock} +struct V { }; +struct A { }; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; -\rSec2[conv.rank]{Conversion ranks}% -\indextext{conversion!integer rank} +void g() { + D d; + B* pb = &d; + A* pa = &d; // error: ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? + V* pv = &d; // OK, only one \tcode{V} subobject +} +\end{codeblock} +\end{example} \pnum -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 -the same representation. - -\item The rank of a signed integer type is greater than the rank -of any signed integer type with a smaller width. - -\item The rank of \tcode{\keyword{long} \keyword{long} \keyword{int}} is greater -than the rank of \tcode{\keyword{long} \keyword{int}}, which is greater than -the rank of \keyword{int}, which is greater than the rank of -\tcode{\keyword{short} \keyword{int}}, which is greater than the rank of -\tcode{\keyword{signed} \keyword{char}}. - -\item The rank of any unsigned integer type equals the rank of the -corresponding signed integer type. - -\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. +\begin{note} +Even if the result of name lookup is unambiguous, use of a name found in +multiple subobjects might still be +ambiguous\iref{conv.mem,expr.ref,class.access.base}. +\end{note} +\begin{example} +\begin{codeblock} +struct B1 { + void f(); + static void f(int); + int i; +}; +struct B2 { + void f(double); +}; +struct I1: B1 { }; +struct I2: B1 { }; -\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 -types\iref{basic.fundamental}. +struct D: I1, I2, B2 { + using B1::f; + using B2::f; + void g() { + f(); // Ambiguous conversion of \keyword{this} + f(0); // Unambiguous (static) + f(0.0); // Unambiguous (only one \tcode{B2}) + int B1::* mpB1 = &D::i; // Unambiguous + int D::* mpD = &D::i; // Ambiguous conversion + } +}; +\end{codeblock} +\end{example} -\item The rank of any extended signed integer type relative to another -extended signed integer type with the same width is \impldef{rank of extended signed -integer type}, but still subject to the other rules for determining the integer -conversion rank. +\rSec2[basic.lookup.unqual]{Unqualified name lookup} -\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if -\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater -rank than \tcode{T3}, then \tcode{T1} has greater rank than -\tcode{T3}. -\end{itemize} +\indextext{name!unqualified}% -\begin{note} -The integer conversion rank is used in the definition of the integral -promotions\iref{conv.prom} and the usual arithmetic -conversions\iref{expr.arith.conv}. -\end{note} +\pnum +A \grammarterm{using-directive} is +\term{active} in a scope $S$ at a program point $P$ +if it precedes $P$ and inhabits either $S$ or +the scope of a namespace nominated by a \grammarterm{using-directive} +that is active in $S$ at $P$. \pnum -Every floating-point type has a \defnadj{floating-point}{conversion rank} -defined as follows: +An \term{unqualified search} in a scope $S$ from a program point $P$ +includes the results of searches from $P$ in \begin{itemize} \item -The rank of a floating point type \tcode{T} is greater than -the rank of any floating-point type -whose set of values is a proper subset of the set of values of \tcode{T}. -\item -The rank of \tcode{\keyword{long} \keyword{double}} is greater than -the rank of \keyword{double}, -which is greater than the rank of \keyword{float}. -\item -Two extended floating-point types with the same set of values have equal ranks. -\item -An extended floating-point type with the same set of values as -exactly one cv-unqualified standard floating-point type -has a rank equal to the rank of that standard floating-point type. +$S$, and \item -An extended floating-point type with the same set of values as -more than one cv-unqualified standard floating-point type -has a rank equal to the rank of \keyword{double}. -\begin{tailnote} -The treatment of \tcode{std::float64_t} differs from -that of the analoguous \tcode{_Float64} in C, -for example on platforms where all of -\tcode{\keyword{long} \keyword{double}}, -\keyword{double}, and -\tcode{std::float64_t} -have the same set of values (see \IsoCUndated{}:2024 H.4.2). -\end{tailnote} +for any scope $U$ that contains $P$ and is or is contained by $S$, +each namespace contained by $S$ that is nominated by +a \grammarterm{using-directive} that is active in $U$ at $P$. \end{itemize} +If no declarations are found, +the results of the unqualified search are +the results of an unqualified search in the parent scope of $S$, if any, +from $P$. \begin{note} -The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} -are unordered if the set of values of \tcode{T1} is -neither a subset nor a superset of the set of values of \tcode{T2}. -This can happen when one type has both a larger range and a lower precision -than the other. -\end{note} - -\pnum -Floating-point types that have equal floating-point conversion ranks -are ordered by floating-point conversion subrank. -The subrank forms a total order among types with equal ranks. -The types -\tcode{std::float16_t}, -\tcode{std::float32_t}, -\tcode{std::float64_t}, and -\tcode{std::float128_t}\iref{stdfloat.syn} -have a greater conversion subrank than any standard floating-point type -with equal conversion rank. -Otherwise, the conversion subrank order is -\impldef{floating-point conversion subrank}. - -\pnum -\begin{note} -The floating-point conversion rank and subrank are used in -the definition of the usual arithmetic conversions\iref{expr.arith.conv}. +When a class scope is searched, +the scopes of its base classes are also searched\iref{class.member.lookup}. +If it inherits from a single base, +it is as if the scope of the base immediately contains +the scope of the derived class. +Template parameter scopes +that are associated with one scope in the chain of parents +are also considered\iref{temp.local}. \end{note} -\rSec1[basic.exec]{Program execution} - -\rSec2[intro.execution]{Sequential execution} -\indextext{program execution|(} +\pnum +\defnx{Unqualified name lookup}{lookup!unqualified name} +from a program point performs an unqualified search in its immediate scope. \pnum -An instance of each object with automatic storage -duration\iref{basic.stc.auto} is associated with each entry into its -block. Such an object exists and retains its last-stored value during -the execution of the block and while the block is suspended (by a call -of a function, suspension of a coroutine\iref{expr.await}, or receipt of a signal). +An \defnadj{unqualified}{name} is a name +that does not immediately follow a \grammarterm{nested-name-specifier} or +the \tcode{.} or \tcode{->} in a class member access expression\iref{expr.ref}, +possibly after a \keyword{template} keyword or \tcode{\~}. +Unless otherwise specified, +such a name undergoes unqualified name lookup from the point where it appears. \pnum -A \defn{constituent expression} is defined as follows: -\begin{itemize} -\item -The constituent expression of an expression is that expression. -\item -The constituent expression of a conversion is -the corresponding implicit function call, if any, or -the converted expression otherwise. -\item -The constituent expressions of a \grammarterm{braced-init-list} or -of a (possibly parenthesized) \grammarterm{expression-list} -are the constituent expressions of the elements of the respective list. -\item -The constituent expressions of a \grammarterm{brace-or-equal-initializer} -of the form \tcode{=}~\grammarterm{initializer-clause} -are the constituent expressions of the \grammarterm{initializer-clause}. -\end{itemize} +An unqualified name that is a component name\iref{expr.prim.id.unqual} of +a \grammarterm{type-specifier} or \grammarterm{ptr-operator} of +a \grammarterm{conversion-type-id} is looked up in the same fashion +as the \grammarterm{conversion-function-id} in which it appears. +If that lookup finds nothing, it undergoes unqualified name lookup; +in each case, only names +that denote types or templates whose specializations are types are considered. \begin{example} \begin{codeblock} -struct A { int x; }; -struct B { int y; struct A a; }; -B b = { 5, { 1+1 } }; +struct T1 { struct U { int i; }; }; +struct T2 { }; +struct U1 {}; +struct U2 {}; + +struct B { + using T = T1; + using U = U1; + operator U1 T1::*(); + operator U1 T2::*(); + operator U2 T1::*(); + operator U2 T2::*(); +}; + +template +int g() { + using U = U2; + X().operator U T::*(); // \#1, searches for \tcode{T} in the scope of \tcode{X} first + X().operator U decltype(T())::*(); // \#2 + return 0; +} +int x = g(); // \#1 calls \tcode{B::operator U1 T1::*} + // \#2 calls \tcode{B::operator U1 T2::*} \end{codeblock} -The constituent expressions of the \grammarterm{initializer} -used for the initialization of \tcode{b} are \tcode{5} and \tcode{1+1}. \end{example} \pnum -The \defnx{immediate subexpressions}{immediate subexpression} of an expression $E$ are -\begin{itemize} -\item -the constituent expressions of $E$'s operands\iref{expr.prop}, -\item -any function call that $E$ implicitly invokes, -\item -if $E$ is a \grammarterm{lambda-expression}\iref{expr.prim.lambda}, -the initialization of the entities captured by copy and -the constituent expressions of the \grammarterm{initializer} of the \grammarterm{init-capture}{s}, -\item -if $E$ is a function call\iref{expr.call} or implicitly invokes a function, -the constituent expressions of each default argument\iref{dcl.fct.default} -used in the call, or -\item -if $E$ creates an aggregate object\iref{dcl.init.aggr}, -the constituent expressions of each default member initializer\iref{class.mem} -used in the initialization. -\end{itemize} +In a friend declaration \grammarterm{declarator} +whose \grammarterm{declarator-id} is a \grammarterm{qualified-id} +whose lookup context\iref{basic.lookup.qual} is a class or namespace $S$, +lookup for an unqualified name +that appears after the \grammarterm{declarator-id} +performs a search in the scope associated with $S$. +If that lookup finds nothing, it undergoes unqualified name lookup. +\begin{example} +\begin{codeblock} +using I = int; +using D = double; +namespace A { + inline namespace N {using C = char; } + using F = float; + void f(I); + void f(D); + void f(C); + void f(F); +} +struct X0 {using F = float; }; +struct W { + using D = void; + struct X : X0 { + void g(I); + void g(::D); + void g(F); + }; +}; +namespace B { + typedef short I, F; + class Y { + friend void A::f(I); // error: no \tcode{void A::f(short)} + friend void A::f(D); // OK + friend void A::f(C); // error: \tcode{A::N::C} not found + friend void A::f(F); // OK + friend void W::X::g(I); // error: no \tcode{void X::g(short)} + friend void W::X::g(D); // OK + friend void W::X::g(F); // OK + }; +} +\end{codeblock} +\end{example} -\pnum -A \defn{subexpression} of an expression $E$ is -an immediate subexpression of $E$ or -a subexpression of an immediate subexpression of $E$. -\begin{note} -Expressions appearing in the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} -are not subexpressions of the \grammarterm{lambda-expression}. -\end{note} -The \defnadjx{potentially-evaluated}{subexpressions}{subexpression} of -an expression, conversion, or \grammarterm{initializer} $E$ are -\begin{itemize} -\item -the constituent expressions of $E$ and -\item -the subexpressions thereof that -are not subexpressions of a nested unevaluated operand\iref{term.unevaluated.operand}. -\end{itemize} +\rSec2[basic.lookup.argdep]{Argument-dependent name lookup}% +\indextext{lookup!argument-dependent} \pnum -A \defn{full-expression} is +When the \grammarterm{postfix-expression} in +a function call\iref{expr.call} is an \grammarterm{unqualified-id}, +and unqualified lookup\iref{basic.lookup.unqual} +for the name in the \grammarterm{unqualified-id} does not find any \begin{itemize} \item -an unevaluated operand\iref{expr.context}, -\item -a \grammarterm{constant-expression}\iref{expr.const}, -\item -an immediate invocation\iref{expr.const}, -\item -an \grammarterm{init-declarator}\iref{dcl.decl} -(including such introduced by a structured binding\iref{dcl.struct.bind}) or -a \grammarterm{mem-initializer}\iref{class.base.init}, -including the constituent expressions of the initializer, +declaration of a class member, or \item -an invocation of a destructor generated at the end of the lifetime -of an object other than a temporary object\iref{class.temporary} -whose lifetime has not been extended, or +function declaration inhabiting a block scope, or \item -an expression that is not a subexpression of another expression and -that is not otherwise part of a full-expression. +declaration not of a function or function template \end{itemize} -If a language construct is defined to produce an implicit call of a function, -a use of the language construct is considered to be an expression -for the purposes of this definition. -Conversions applied to the result of an expression in order to satisfy the requirements -of the language construct in which the expression appears -are also considered to be part of the full-expression. -For an initializer, performing the initialization of the entity -(including evaluating default member initializers of an aggregate) -is also considered part of the full-expression. +then lookup for the name also includes the result of +\defnadj{argument-dependent}{lookup} in a set of associated namespaces +that depends on the types of the arguments +(and for template template arguments, the namespace of the template argument), +as specified below. \begin{example} \begin{codeblock} -struct S { - S(int i): I(i) { } // full-expression is initialization of \tcode{I} - int& v() { return I; } - ~S() noexcept(false) { } -private: - int I; -}; +namespace N { + struct S { }; + void f(S); +} -S s1(1); // full-expression comprises call of \tcode{S::S(int)} -void f() { - S s2 = 2; // full-expression comprises call of \tcode{S::S(int)} - if (S(3).v()) // full-expression includes lvalue-to-rvalue and \tcode{int} to \tcode{bool} conversions, - // performed before temporary is deleted at end of full-expression - { } - bool b = noexcept(S(4)); // exception specification of destructor of \tcode{S} considered for \keyword{noexcept} +void g() { + N::S s; + f(s); // OK, calls \tcode{N::f} + (f)(s); // error: \tcode{N::f} not considered; parentheses prevent argument-dependent lookup +} +\end{codeblock} +\end{example} - // full-expression is destruction of \tcode{s2} at end of block +\pnum +\begin{note} +For purposes of determining +(during parsing) whether an expression is a +\grammarterm{postfix-expression} for a function call, the usual name lookup +rules apply. +In some cases +a name followed by \tcode{<} is treated as a \grammarterm{template-name} +even though name lookup did not find a \grammarterm{template-name} +(see \ref{temp.names}). +For example, +\begin{codeblock} +int h; +void g(); +namespace N { + struct A {}; + template int f(T); + template int g(T); + template int h(T); +} + +int x = f(N::A()); // OK, lookup of \tcode{f} finds nothing, \tcode{f} treated as template name +int y = g(N::A()); // OK, lookup of \tcode{g} finds a function, \tcode{g} treated as template name +int z = h(N::A()); // error: \tcode{h<} does not begin a \grammarterm{template-id} +\end{codeblock} + +The rules have no effect on the syntactic interpretation of an expression. +For example, +\begin{codeblock} +typedef int f; +namespace N { + struct A { + friend void f(A &); + operator int(); + void g(A a) { + int i = f(a); // \tcode{f} is the typedef, not the friend function: equivalent to \tcode{int(a)} + } + }; } -struct B { - B(S = S(0)); -}; -B b[2] = { B(), B() }; // full-expression is the entire initialization - // including the destruction of temporaries \end{codeblock} -\end{example} - -\pnum -\begin{note} -The evaluation of a full-expression can include the -evaluation of subexpressions that are not lexically part of the -full-expression. For example, subexpressions involved in evaluating -default arguments\iref{dcl.fct.default} are considered to -be created in the expression that calls the function, not the expression -that defines the default argument. +Because the expression is not a function call, +argument-dependent name lookup does not apply and +the friend function \tcode{f} is not found. \end{note} \pnum -\indextext{value computation|(}% -Reading an object designated by a \keyword{volatile} -glvalue\iref{basic.lval}, modifying an object, calling a library I/O -function, or calling a function that does any of those operations are -all -\defn{side effects}, which are changes in the state of the execution -environment. \defnx{Evaluation}{evaluation} of an expression (or a -subexpression) in general includes both value computations (including -determining the identity of an object for glvalue evaluation and fetching -a value previously assigned to an object for prvalue evaluation) and -initiation of side effects. When a call to a library I/O function -returns or an access through a volatile glvalue is evaluated, the side -effect is considered complete, even though some external actions implied -by the call (such as the I/O itself) or by the \keyword{volatile} access -may not have completed yet. +For each argument type \tcode{T} in the function call, +there is a set of zero or more \defnx{associated entities}{entity!associated} +to be considered. +The set of entities is determined entirely by +the types of the function arguments +(and any template template arguments). +Any \grammarterm{typedef-name}s and \grammarterm{using-declaration}{s} +used to specify the types +do not contribute to this set. +The set of entities +is determined in the following way: +\begin{itemize} +\item If \tcode{T} is a fundamental type, its associated set of +entities is empty. -\pnum -\defnx{Sequenced before}{sequenced before} is an asymmetric, transitive, pair-wise relation between -evaluations executed by a single thread\iref{intro.multithread}, which induces -a partial order among those evaluations. Given any two evaluations \placeholder{A} and -\placeholder{B}, if \placeholder{A} is sequenced before \placeholder{B} -(or, equivalently, \placeholder{B} is \defn{sequenced after} \placeholder{A}), -then the execution of -\placeholder{A} shall precede the execution of \placeholder{B}. If \placeholder{A} is not sequenced -before \placeholder{B} and \placeholder{B} is not sequenced before \placeholder{A}, then \placeholder{A} and -\placeholder{B} are \defn{unsequenced}. -\begin{note} -The execution of unsequenced -evaluations can overlap. -\end{note} -Evaluations \placeholder{A} and \placeholder{B} are -\defn{indeterminately sequenced} when either \placeholder{A} is sequenced before -\placeholder{B} or \placeholder{B} is sequenced before \placeholder{A}, but it is unspecified which. +\item If \tcode{T} is a class type (including unions), +its associated entities are: +the class itself; +the class of which it is a member, if any; +and, if it is a complete type, its direct and indirect base classes. +Furthermore, if \tcode{T} is a class template specialization, +its associated entities also include: +the entities +associated with the types of the template arguments +provided for template type parameters; +the templates used as template template arguments; and +the classes of which any member templates used as template template +arguments are members. \begin{note} -Indeterminately sequenced evaluations cannot overlap, but either -can be executed first. +Non-type template arguments do not +contribute to the set of associated entities. \end{note} -An expression \placeholder{X} -is said to be sequenced before -an expression \placeholder{Y} if -every value computation and every side effect -associated with the expression \placeholder{X} -is sequenced before -every value computation and every side effect -associated with the expression \placeholder{Y}. -\pnum -Every -\indextext{value computation}% -value computation and -\indextext{side effects}% -side effect associated with a full-expression is -sequenced before every value computation and side effect associated with the -next full-expression to be evaluated. -\begin{footnote} -As specified -in~\ref{class.temporary}, after a full-expression is evaluated, a sequence of -zero or more invocations of destructor functions for temporary objects takes -place, usually in reverse order of the construction of each temporary object. -\end{footnote} +\item If \tcode{T} is an enumeration type, +its associated entities are \tcode{T} +and, if it is a class member, the member's class. -\pnum -\indextext{evaluation!unspecified order of}% -Except where noted, evaluations of operands of individual operators and -of subexpressions of individual expressions are unsequenced. -\begin{note} -In an expression that is evaluated more than once during the execution -of a program, unsequenced and indeterminately sequenced evaluations of -its subexpressions need not be performed consistently in different -evaluations. -\end{note} -The value computations of the operands of an -operator are sequenced before the value computation of the result of the -operator. If a -\indextext{side effects}% -side effect on a memory location\iref{intro.memory} is unsequenced -relative to either another side effect on the same memory location or -a value computation using the value of any object in the same memory location, -and they are not potentially concurrent\iref{intro.multithread}, -the behavior is undefined. -\begin{note} -The next subclause imposes similar, but more complex restrictions on -potentially concurrent computations. -\end{note} +\item If \tcode{T} is a pointer to \tcode{U} or an array of \tcode{U}, +its associated entities are those associated with \tcode{U}. -\begin{example} -\begin{codeblock} -void g(int i) { - i = 7, i++, i++; // \tcode{i} becomes \tcode{9} +\item If \tcode{T} is a function type, its associated +entities are those associated with the function parameter types and those +associated with the return type. - i = i++ + 1; // the value of \tcode{i} is incremented - i = i++ + i; // undefined behavior - i = i + 1; // the value of \tcode{i} is incremented -} -\end{codeblock} -\end{example} +\item If \tcode{T} is a pointer to a member function of a class +\tcode{X}, its associated entities are those associated +with the function parameter types and return type, together with those +associated with \tcode{X}. -\pnum -When invoking a function (whether or not the function is inline), -every argument expression and -the postfix expression designating the called function -are sequenced before every expression or statement -in the body of the called function. -For each function invocation or -evaluation of an \grammarterm{await-expression} \placeholder{F}, -each evaluation that does not occur within \placeholder{F} but -is evaluated on the same thread and as part of the same signal handler (if any) -is either sequenced before all evaluations that occur within \placeholder{F} -or sequenced after all evaluations that occur within \placeholder{F}; -\begin{footnote} -In other words, -function executions do not interleave with each other. -\end{footnote} -if \placeholder{F} invokes or resumes a coroutine\iref{expr.await}, -only evaluations -subsequent to the previous suspension (if any) and -prior to the next suspension (if any) -are considered to occur within \placeholder{F}. +\item If \tcode{T} is a pointer to a data member of class \tcode{X}, its +associated entities are those associated with the member +type together with those associated with \tcode{X}. +\end{itemize} +In addition, if the argument is an overload set or the address of such a set, +its associated entities +are the union of those associated with each of the +members of the set, i.e., the entities associated with its +parameter types and return type. +Additionally, if the aforementioned overload set is named with +a \grammarterm{template-id}, its associated entities also include +its template \grammarterm{template-argument}{s} and +those associated with its type \grammarterm{template-argument}s. -Several contexts in \Cpp{} cause evaluation of a function call, even -though no corresponding function call syntax appears in the translation -unit. -\begin{example} -Evaluation of a \grammarterm{new-expression} invokes one or more allocation -and constructor functions; see~\ref{expr.new}. For another example, -invocation of a conversion function\iref{class.conv.fct} can arise in -contexts in which no function call syntax appears. -\end{example} -The sequencing constraints on the execution of the called function (as -described above) are features of the function calls as evaluated, -regardless of the syntax of the expression that calls the function.% -\indextext{value computation|)}% +\pnum +The \term{associated namespaces} for a call are +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 +\begin{itemize} +\item +are found by a search of 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 +\item +are exported, +are attached to a named module \tcode{M}\iref{module.interface}, +do not appear in the translation unit containing the point of the lookup, and +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}, +the above lookup is also performed +from each point in the instantiation context\iref{module.context} of the lookup, +additionally ignoring any declaration that +appears in another translation unit, +is attached to the global module, and +is either discarded\iref{module.global.frag} or has internal linkage. -\indextext{behavior!on receipt of signal}% -\indextext{signal}% \pnum -If a signal handler is executed as a result of a call to the \tcode{std::raise} -function, then the execution of the handler is sequenced after the invocation -of the \tcode{std::raise} function and before its return. -\begin{note} -When a signal is received for another reason, the execution of the -signal handler is usually unsequenced with respect to the rest of the program. -\end{note} +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M; +namespace R { + export struct X {}; + export void f(X); +} +namespace S { + export void f(R::X, R::X); +} +\end{codeblocktu} -\rSec2[intro.multithread]{Multi-threaded executions and data races} +\begin{codeblocktu}{Translation unit \#2} +export module N; +import M; +export R::X make(); +namespace R { static int g(X); } +export template void apply(T t, U u) { + f(t, u); + g(t); +} +\end{codeblocktu} -\rSec3[intro.multithread.general]{General} +\begin{codeblocktu}{Translation unit \#3} +module Q; +import N; +namespace S { + struct Z { template operator T(); }; +} +void test() { + auto x = make(); // OK, \tcode{decltype(x)} is \tcode{R::X} in module \tcode{M} + R::f(x); // error: \tcode{R} and \tcode{R::f} are not visible here + f(x); // OK, calls \tcode{R::f} from interface of \tcode{M} + f(x, S::Z()); // error: \tcode{S::f} in module \tcode{M} not considered + // even though \tcode{S} is an associated namespace + apply(x, S::Z()); // error: \tcode{S::f} is visible in instantiation context, but + // \tcode{R::g} has internal linkage and cannot be used outside TU \#2 +} +\end{codeblocktu} +\end{example} \pnum -\indextext{threads!multiple|(}% -\indextext{atomic!operation|(}% -A \defn{thread of execution} (also known as a \defn{thread}) is a single flow of -control within a program, including the initial invocation of a specific -top-level function, and recursively including every function invocation -subsequently executed by the thread. -\begin{note} -When one thread creates another, -the initial call to the top-level function of the new thread is executed by the -new thread, not by the creating thread. -\end{note} -Every thread in a program can -potentially access every object and function in a program. -\begin{footnote} -An object -with automatic or thread storage duration\iref{basic.stc} is associated with -one specific thread, and can be accessed by a different thread only indirectly -through a pointer or reference\iref{basic.compound}. -\end{footnote} -Under a hosted -implementation, a \Cpp{} program can have more than one thread running -concurrently. The execution of each thread proceeds as defined by the remainder -of this document. The execution of the entire program consists of an execution -of all of its threads. \begin{note} -Usually the execution can be viewed as an -interleaving of all its threads. However, some kinds of atomic operations, for -example, allow executions inconsistent with a simple interleaving, as described -below. +The associated namespace can include namespaces +already considered by ordinary unqualified lookup. \end{note} -\indextext{implementation!freestanding}% -Under a freestanding implementation, it is \impldef{number of -threads in a program under a freestanding implementation} whether a program can -have more than one thread of execution. +\begin{example} +\begin{codeblock} +namespace NS { + class T { }; + void f(T); + void g(T, int); +} +NS::T parm; +void g(NS::T, float); +int main() { + f(parm); // OK, calls \tcode{NS::f} + extern void g(NS::T, float); + g(parm, 1); // OK, calls \tcode{g(NS::T, float)} +} +\end{codeblock} +\end{example} -\pnum -For a signal handler that is not executed as a result of a call to the -\tcode{std::raise} function, it is unspecified which thread of execution -contains the signal handler invocation. +\rSec2[basic.lookup.qual]{Qualified name lookup} -\rSec3[intro.races]{Data races} +\rSec3[basic.lookup.qual.general]{General} \pnum -The value of an object visible to a thread $T$ at a particular point is the -initial value of the object, a value assigned to the object by $T$, or a -value assigned to the object by another thread, according to the rules below. -\begin{note} -In some cases, there might instead be undefined behavior. Much of this -subclause is motivated by the desire to support atomic operations with explicit -and detailed visibility constraints. However, it also implicitly supports a -simpler view for more restricted programs. -\end{note} +\indextext{lookup!qualified name|(}% +\indextext{name!qualified}% +\indextext{qualification!explicit}% +Lookup of an \grammarterm{identifier} +followed by a \tcode{::} scope resolution operator +considers only +namespaces, types, and templates whose specializations are types. +If a name, \grammarterm{template-id}, or \grammarterm{computed-type-specifier} +is followed by a \tcode{::}, +it shall designate a namespace, class, enumeration, or dependent type, +and the \tcode{::} is never interpreted as +a complete \grammarterm{nested-name-specifier}. +\begin{example} +\begin{codeblock} +class A { +public: + static int n; +}; +int main() { + int A; + A::n = 42; // OK + A b; // error: \tcode{A} does not name a type +} +template struct B : A {}; +namespace N { + template void B(); + int f() { + return B<0>::n; // error: \tcode{N::B<0>} is not a type + } +} +\end{codeblock} +\end{example} -\pnum -Two expression evaluations \defn{conflict} if one of them modifies a memory -location\iref{intro.memory} and the other one reads or modifies the same -memory location. +\indextext{operator!scope resolution}% +\indextext{scope resolution operator|see{operator, scope resolution}}% \pnum -The library defines a number of atomic operations\iref{atomics} and -operations on mutexes\iref{thread} that are specially identified as -synchronization operations. These operations play a special role in making -assignments in one thread visible to another. A synchronization operation on one -or more memory locations is either a consume operation, an acquire operation, a -release operation, or both an acquire and release operation. A synchronization -operation without an associated memory location is a fence and can be either an -acquire fence, a release fence, or both an acquire and release fence. In -addition, there are relaxed atomic operations, which are not synchronization -operations, and atomic read-modify-write operations, which have special -characteristics. +A member-qualified name is +the (unique) component name\iref{expr.prim.id.unqual}, if any, of +\begin{itemize} +\item +an \grammarterm{unqualified-id} or +\item +a \grammarterm{nested-name-specifier} of the form +\grammarterm{type-name} \tcode{::} or \grammarterm{namespace-name} \tcode{::} +\end{itemize} +in the \grammarterm{id-expression} of a class member access expression\iref{expr.ref}. +A \defnadj{qualified}{name} is +\begin{itemize} +\item a member-qualified name or +\item the terminal name of +\begin{itemize} +\item a \grammarterm{qualified-id}, +\item a \grammarterm{using-declarator}, +\item a \grammarterm{typename-specifier}, +\item a \grammarterm{qualified-namespace-specifier}, or +\item a \grammarterm{nested-name-specifier}, +\grammarterm{elaborated-type-specifier}, or +\grammarterm{class-or-decltype} +that has a \grammarterm{nested-name-specifier}\iref{expr.prim.id.qual}. +\end{itemize} +\end{itemize} +The \defn{lookup context} of a member-qualified name is +the type of its associated object expression +(considered dependent if the object expression is type-dependent). +The lookup context of any other qualified name is +the type, template, or namespace +nominated by the preceding \grammarterm{nested-name-specifier}. \begin{note} -For example, a call that acquires a mutex will -perform an acquire operation on the locations comprising the mutex. -Correspondingly, a call that releases the same mutex will perform a release -operation on those same locations. Informally, performing a release operation on -$A$ forces prior -\indextext{side effects}% -side effects on other memory locations to become visible -to other threads that later perform a consume or an acquire operation on -$A$. ``Relaxed'' atomic operations are not synchronization operations even -though, like synchronization operations, they cannot contribute to data races. +When parsing a class member access, +the name following the \tcode{->} or \tcode{.} is +a qualified name even though it is not yet known of which kind. \end{note} +\begin{example} +In +\begin{codeblock} + N::C::m.Base::f() +\end{codeblock} +\tcode{Base} is a member-qualified name; +the other qualified names are \tcode{C}, \tcode{m}, and \tcode{f}. +\end{example} \pnum -All modifications to a particular atomic object $M$ occur in some -particular total order, called the \defn{modification order} of $M$. +\defnx{Qualified name lookup}{lookup!qualified name} +in a class, namespace, or enumeration performs +a search of the scope associated with it\iref{class.member.lookup} +except as specified below. +Unless otherwise specified, +a qualified name undergoes qualified name lookup in its lookup context +from the point where it appears +unless the lookup context either +is dependent and is not the current instantiation\iref{temp.dep.type} or +is not a class or class template. +If nothing is found by qualified lookup for a member-qualified name +that is the terminal name\iref{expr.prim.id.unqual} of +a \grammarterm{nested-name-specifier} and +is not dependent, it undergoes unqualified lookup. \begin{note} -There is a separate order for each -atomic object. There is no requirement that these can be combined into a single -total order for all objects. In general this will be impossible since different -threads can observe modifications to different objects in inconsistent orders. +During lookup for a template specialization, no names are dependent. \end{note} +\begin{example} +\begin{codeblock} +int f(); +struct A { + int B, C; + template using D = void; + using T = void; + void f(); +}; +using B = A; +template using C = A; +template using D = A; +template using X = A; -\pnum -A \defn{release sequence} headed -by a release operation $A$ on an atomic object $M$ -is a maximal contiguous sub-sequence of -\indextext{side effects}% -side effects in the modification order of $M$, -where the first operation is $A$, and -every subsequent operation is an atomic read-modify-write operation. - -\pnum -Certain library calls \defn{synchronize with} other library calls performed by -another thread. For example, an atomic store-release synchronizes with a -load-acquire that takes its value from the store\iref{atomics.order}. -\begin{note} -Except in the specified cases, reading a later value does not -necessarily ensure visibility as described below. Such a requirement would -sometimes interfere with efficient implementation. -\end{note} -\begin{note} -The -specifications of the synchronization operations define when one reads the value -written by another. For atomic objects, the definition is clear. All operations -on a given mutex occur in a single total order. Each mutex acquisition ``reads -the value written'' by the last mutex release. -\end{note} +template +void g(T *p) { // as instantiated for \tcode{g}: + p->X<0>::f(); // error: \tcode{A::X} not found in \tcode{((p->X) < 0) > ::f()} + p->template X<0>::f(); // OK, \tcode{::X} found in definition context + p->B::f(); // OK, non-type \tcode{A::B} ignored + p->template C<0>::f(); // error: \tcode{A::C} is not a template + p->template D<0>::f(); // error: \tcode{A::D<0>} is not a class type + p->T::f(); // error: \tcode{A::T} is not a class type +} +template void g(A*); +\end{codeblock} +\end{example} \pnum -An evaluation $A$ \defn{carries a dependency} to an evaluation $B$ if -\begin{itemize} -\item -the value of $A$ is used as an operand of $B$, unless: +If a qualified name $Q$ follows a \tcode{\~}: \begin{itemize} \item -$B$ is an invocation of any specialization of -\tcode{std::kill_dependency}\iref{atomics.order}, or +If $Q$ is a member-qualified name, +it undergoes unqualified lookup as well as qualified lookup. \item -$A$ is the left operand of a built-in logical \logop{and} (\tcode{\&\&}, -see~\ref{expr.log.and}) or logical \logop{or} (\tcode{||}, see~\ref{expr.log.or}) -operator, or +Otherwise, its \grammarterm{nested-name-specifier} $N$ shall nominate a type. +If $N$ has another \grammarterm{nested-name-specifier} $S$, +$Q$ is looked up as if its lookup context were that nominated by $S$. \item -$A$ is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) -operator, or +Otherwise, if the terminal name of $N$ is a member-qualified name $M$, +$Q$ is looked up as if $\tcode{\~}Q$ appeared in place of $M$ (as above). \item -$A$ is the left operand of the built-in comma (\tcode{,}) -operator\iref{expr.comma}; \end{itemize} or +Otherwise, $Q$ undergoes unqualified lookup. \item -$A$ writes a scalar object or bit-field $M$, $B$ reads the value -written by $A$ from $M$, and $A$ is sequenced before $B$, or +Each lookup for $Q$ considers only +types (if $Q$ is not followed by a \tcode{<}) and +templates whose specializations are types. +If it finds nothing or is ambiguous, it is discarded. \item -for some evaluation $X$, $A$ carries a dependency to $X$, and -$X$ carries a dependency to $B$. +The \grammarterm{type-name} that is or contains $Q$ +shall refer to its (original) lookup context (ignoring cv-qualification) under +the interpretation established by at least one (successful) lookup performed. \end{itemize} -\begin{note} -``Carries a dependency to'' is a subset of ``is sequenced before'', -and is similarly strictly intra-thread. -\end{note} - -\pnum -An evaluation $A$ is \defn{dependency-ordered before} an evaluation -$B$ if -\begin{itemize} -\item -$A$ performs a release operation on an atomic object $M$, and, in -another thread, $B$ performs a consume operation on $M$ and reads -the value written by $A$, or +\begin{example} +\begin{codeblock} +struct C { + typedef int I; +}; +typedef int I1, I2; +extern int* p; +extern int* q; +void f() { + p->C::I::~I(); // \tcode{I} is looked up in the scope of \tcode{C} + q->I1::~I2(); // \tcode{I2} is found by unqualified lookup +} +struct A { + ~A(); +}; +typedef A AB; +int main() { + AB* p; + p->AB::~AB(); // explicitly calls the destructor for \tcode{A} +} +\end{codeblock} +\end{example} -\item -for some evaluation $X$, $A$ is dependency-ordered before $X$ and -$X$ carries a dependency to $B$. +\rSec3[class.qual]{Class members} -\end{itemize} -\begin{note} -The relation ``is dependency-ordered before'' is analogous to -``synchronizes with'', but uses release/consume in place of release/acquire. -\end{note} +\indextext{lookup!class member}% \pnum -An evaluation $A$ \defn{inter-thread happens before} an evaluation $B$ -if +In a lookup for a qualified name $N$ whose lookup context is a class $C$ +in which function names are not ignored, +\begin{footnote} +Lookups in which +function names are ignored include names appearing in a +\grammarterm{nested-name-specifier}, an +\grammarterm{elaborated-type-specifier}, or a \grammarterm{base-specifier}. +\end{footnote} \begin{itemize} \item - $A$ synchronizes with $B$, or -\item - $A$ is dependency-ordered before $B$, or +if the search finds the injected-class-name of \tcode{C}\iref{class.pre}, or \item - for some evaluation $X$ - \begin{itemize} - \item - $A$ synchronizes with $X$ and $X$ - is sequenced before $B$, or - \item - $A$ is sequenced before $X$ and $X$ - inter-thread happens before $B$, or - \item - $A$ inter-thread happens before $X$ and $X$ - inter-thread happens before $B$. - \end{itemize} +if $N$ is dependent and +is the terminal name of a \grammarterm{using-declarator}\iref{namespace.udecl} +that names a constructor, \end{itemize} -\begin{note} -The ``inter-thread happens before'' relation describes arbitrary -concatenations of ``sequenced before'', ``synchronizes with'' and -``dependency-ordered before'' relationships, with two exceptions. The first -exception is that a concatenation never ends with -``dependency-ordered before'' followed by ``sequenced before''. The reason for -this limitation is that a consume operation participating in a -``dependency-ordered before'' relationship provides ordering only with respect -to operations to which this consume operation actually carries a dependency. The -reason that this limitation applies only to the end of such a concatenation is -that any subsequent release operation will provide the required ordering for a -prior consume operation. The second exception is that a concatenation never -consist entirely of ``sequenced before''. The reasons for this -limitation are (1) to permit ``inter-thread happens before'' to be transitively -closed and (2) the ``happens before'' relation, defined below, provides for -relationships consisting entirely of ``sequenced before''. -\end{note} +$N$ is instead considered to name the constructor of class \tcode{C}. +Such a constructor name shall be used only +in the \grammarterm{declarator-id} of a (friend) declaration of a constructor or +in a \grammarterm{using-declaration}. +\begin{example} +\begin{codeblock} +struct A { A(); }; +struct B: public A { B(); }; -\pnum -An evaluation $A$ \defn{happens before} an evaluation $B$ -(or, equivalently, $B$ \defn{happens after} $A$) if -\begin{itemize} -\item $A$ is sequenced before $B$, or -\item $A$ inter-thread happens before $B$. -\end{itemize} -The implementation shall ensure that no program execution demonstrates a cycle -in the ``happens before'' relation. -\begin{note} -This cycle would otherwise be -possible only through the use of consume operations. -\end{note} +A::A() { } +B::B() { } -\pnum -An evaluation $A$ \defn{simply happens before} an evaluation $B$ -if either -\begin{itemize} -\item $A$ is sequenced before $B$, or -\item $A$ synchronizes with $B$, or -\item $A$ simply happens before $X$ and -$X$ simply happens before $B$. -\end{itemize} -\begin{note} -In the absence of consume operations, -the happens before and simply happens before relations are identical. -\end{note} +B::A ba; // object of type \tcode{A} +A::A a; // error: \tcode{A::A} is not a type name +struct A::A a2; // object of type \tcode{A} +\end{codeblock} +\end{example} + +\rSec3[namespace.qual]{Namespace members} \pnum -An evaluation $A$ \defn{strongly happens before} -an evaluation $D$ if, either -\begin{itemize} -\item $A$ is sequenced before $D$, or -\item $A$ synchronizes with $D$, and -both $A$ and $D$ are -sequentially consistent atomic operations\iref{atomics.order}, or -\item there are evaluations $B$ and $C$ -such that $A$ is sequenced before $B$, -$B$ simply happens before $C$, and -$C$ is sequenced before $D$, or -\item there is an evaluation $B$ such that -$A$ strongly happens before $B$, and -$B$ strongly happens before $D$. -\end{itemize} +Qualified name lookup in a namespace $N$ additionally searches +every element of the inline namespace set of $N$\iref{namespace.def}. +If nothing is found, +the results of the lookup are the results of qualified name lookup +in each namespace nominated by a \grammarterm{using-directive} +that precedes the point of the lookup and +inhabits $N$ or an element of $N$'s inline namespace set. \begin{note} -Informally, if $A$ strongly happens before $B$, -then $A$ appears to be evaluated before $B$ -in all contexts. Strongly happens before excludes consume operations. +If a \grammarterm{using-directive} refers to a namespace +that has already been considered, it does not affect the result. \end{note} +\begin{example} +\begin{codeblock} +int x; +namespace Y { + void f(float); + void h(int); +} -\pnum -A \defnadjx{visible}{side effect}{side effects} $A$ on a scalar object or bit-field $M$ -with respect to a value computation $B$ of $M$ satisfies the -conditions: -\begin{itemize} -\item $A$ happens before $B$ and -\item there is no other -\indextext{side effects}% -side effect $X$ to $M$ such that $A$ -happens before $X$ and $X$ happens before $B$. -\end{itemize} +namespace Z { + void h(double); +} -The value of a non-atomic scalar object or bit-field $M$, as determined by -evaluation $B$, is the value stored by the -\indextext{side effects!visible}% -visible side effect $A$. -\begin{note} -If there is ambiguity about which side effect to a -non-atomic object or bit-field is visible, then the behavior is either -unspecified or undefined. -\end{note} -\begin{note} -This states that operations on -ordinary objects are not visibly reordered. This is not actually detectable -without data races, but is needed to ensure that data races, as defined -below, and with suitable restrictions on the use of atomics, correspond to data -races in a simple interleaved (sequentially consistent) execution. -\end{note} +namespace A { + using namespace Y; + void f(int); + void g(int); + int i; +} + +namespace B { + using namespace Z; + void f(char); + int i; +} + +namespace AB { + using namespace A; + using namespace B; + void g(); +} + +void h() +{ + AB::g(); // \tcode{g} is declared directly in \tcode{AB}, therefore \tcode{S} is $\{ \tcode{AB::g()} \}$ and \tcode{AB::g()} is chosen -\pnum -The value of an -atomic object $M$, as determined by evaluation $B$, is the value -stored by some unspecified -side effect $A$ that modifies $M$, where $B$ does not happen -before $A$. -\begin{note} -The set of such side effects is also restricted by the rest of the rules -described here, and in particular, by the coherence requirements below. -\end{note} + AB::f(1); // \tcode{f} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}; + // namespace \tcode{Y} is not searched and \tcode{Y::f(float)} is not considered; + // \tcode{S} is $\{ \tcode{A::f(int)}, \tcode{B::f(char)} \}$ and overload resolution chooses \tcode{A::f(int)} -\pnum -\indextext{coherence!write-write}% -If an operation $A$ that modifies an atomic object $M$ happens before -an operation $B$ that modifies $M$, then $A$ is earlier -than $B$ in the modification order of $M$. -\begin{note} -This requirement is known as write-write coherence. -\end{note} + AB::f('c'); // as above but resolution chooses \tcode{B::f(char)} -\pnum -\indextext{coherence!read-read}% -If a -\indextext{value computation}% -value computation $A$ of an atomic object $M$ happens before a -value computation $B$ of $M$, and $A$ takes its value from a side -effect $X$ on $M$, then the value computed by $B$ is either -the value stored by $X$ or the value stored by a -\indextext{side effects}% -side effect $Y$ on $M$, -where $Y$ follows $X$ in the modification order of $M$. -\begin{note} -This requirement is known as read-read coherence. -\end{note} + AB::x++; // \tcode{x} is not declared directly in \tcode{AB}, and is not declared in \tcode{A} or \tcode{B}, so the rules + // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \}$ so the program is ill-formed -\pnum -\indextext{coherence!read-write}% -If a -\indextext{value computation}% -value computation $A$ of an atomic object $M$ happens before an -operation $B$ that modifies $M$, then $A$ takes its value from a side -effect $X$ on $M$, where $X$ precedes $B$ in the -modification order of $M$. -\begin{note} -This requirement is known as -read-write coherence. -\end{note} + AB::i++; // \tcode{i} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}, + // \tcode{S} is $\{ \tcode{A::i}, \tcode{B::i} \}$ so the use is ambiguous and the program is ill-formed -\pnum -\indextext{coherence!write-read}% -If a -\indextext{side effects}% -side effect $X$ on an atomic object $M$ happens before a value -computation $B$ of $M$, then the evaluation $B$ takes its -value from $X$ or from a -\indextext{side effects}% -side effect $Y$ that follows $X$ in the modification order of $M$. -\begin{note} -This requirement is known as write-read coherence. -\end{note} + AB::h(16.8); // \tcode{h} is not declared directly in \tcode{AB} and not declared directly in \tcode{A} or \tcode{B} so the rules + // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \tcode{Y::h(int)}, \tcode{Z::h(double)} \}$ and + // overload resolution chooses \tcode{Z::h(double)} +} +\end{codeblock} +\end{example} \pnum \begin{note} -The four preceding coherence requirements effectively disallow -compiler reordering of atomic operations to a single object, even if both -operations are relaxed loads. This effectively makes the cache coherence -guarantee provided by most hardware available to \Cpp{} atomic operations. -\end{note} +The same declaration found more than once is not an ambiguity (because +it is still a unique declaration). +\begin{example} +\begin{codeblock} +namespace A { + int a; +} -\pnum -\begin{note} -The value observed by a load of an atomic depends on the ``happens -before'' relation, which depends on the values observed by loads of atomics. -The intended reading is that there must exist an -association of atomic loads with modifications they observe that, together with -suitably chosen modification orders and the ``happens before'' relation derived -as described above, satisfy the resulting constraints as imposed here. -\end{note} +namespace B { + using namespace A; +} -\pnum -Two actions are \defn{potentially concurrent} if -\begin{itemize} -\item they are performed by different threads, or -\item they are unsequenced, at least one is performed by a signal handler, and -they are not both performed by the same signal handler invocation. -\end{itemize} -The execution of a program contains a \defn{data race} if it contains two -potentially concurrent conflicting actions, at least one of which is not atomic, -and neither happens before the other, -except for the special case for signal handlers described below. -Any such data race results in undefined -behavior. -\begin{note} -It can be shown that programs that correctly use mutexes -and \tcode{memory_order::seq_cst} operations to prevent all data races and use no -other synchronization operations behave as if the operations executed by their -constituent threads were simply interleaved, with each -\indextext{value computation}% -value computation of an -object being taken from the last -\indextext{side effects}% -side effect on that object in that -interleaving. This is normally referred to as ``sequential consistency''. -However, this applies only to data-race-free programs, and data-race-free -programs cannot observe most program transformations that do not change -single-threaded program semantics. In fact, most single-threaded program -transformations remain possible, since any program that behaves -differently as a result has undefined behavior. -\end{note} +namespace C { + using namespace A; +} -\pnum -Two accesses to the same object of type \tcode{\keyword{volatile} std::sig_atomic_t} do not -result in a data race if both occur in the same thread, even if one or more -occurs in a signal handler. For each signal handler invocation, evaluations -performed by the thread invoking a signal handler can be divided into two -groups $A$ and $B$, such that no evaluations in -$B$ happen before evaluations in $A$, and the -evaluations of such \tcode{\keyword{volatile} std::sig_atomic_t} objects take values as though -all evaluations in $A$ happened before the execution of the signal -handler and the execution of the signal handler happened before all evaluations -in $B$. +namespace BC { + using namespace B; + using namespace C; +} -\pnum -\begin{note} -Compiler transformations that introduce assignments to a potentially -shared memory location that would not be modified by the abstract machine are -generally precluded by this document, since such an assignment might overwrite -another assignment by a different thread in cases in which an abstract machine -execution would not have encountered a data race. This includes implementations -of data member assignment that overwrite adjacent members in separate memory -locations. Reordering of atomic loads in cases in which the atomics in question -might alias is also generally precluded, since this could violate the coherence -rules. -\end{note} +void f() +{ + BC::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ +} -\pnum -\begin{note} -It is possible that transformations that introduce a speculative read of a potentially -shared memory location do not preserve the semantics of the \Cpp{} program as -defined in this document, since they potentially introduce a data race. However, -they are typically valid in the context of an optimizing compiler that targets a -specific machine with well-defined semantics for data races. They would be -invalid for a hypothetical machine that is not tolerant of races or provides -hardware race detection. -\end{note} +namespace D { + using A::a; +} -\rSec3[intro.progress]{Forward progress} +namespace BD { + using namespace B; + using namespace D; +} -\pnum -The implementation may assume that any thread will eventually do one of the -following: -\begin{itemize} -\item terminate, -\item invoke the function \tcode{std::this_thread::yield}\iref{thread.thread.this}, -\item make a call to a library I/O function, -\item perform an access through a volatile glvalue, -\item perform a synchronization operation or an atomic operation, or -\item continue execution of a trivial infinite loop\iref{stmt.iter.general}. -\end{itemize} -\begin{note} -This is intended to allow compiler transformations -such as removal, merging, and reordering of empty loops, -even when termination cannot be proven. -An affordance is made for trivial infinite loops, -which cannot be removed nor reordered. +void g() +{ + BD::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ +} +\end{codeblock} +\end{example} \end{note} \pnum -Executions of atomic functions -that are either defined to be lock-free\iref{atomics.flag} -or indicated as lock-free\iref{atomics.lockfree} -are \defnx{lock-free executions}{lock-free execution}. -\begin{itemize} -\item - If there is only one thread that is not blocked\iref{defns.block} - in a standard library function, - a lock-free execution in that thread shall complete. - \begin{note} - Concurrently executing threads - might prevent progress of a lock-free execution. - For example, - this situation can occur - with load-locked store-conditional implementations. - This property is sometimes termed obstruction-free. - \end{note} -\item - When one or more lock-free executions run concurrently, - at least one should complete. - \begin{note} - It is difficult for some implementations - to provide absolute guarantees to this effect, - since repeated and particularly inopportune interference - from other threads - could prevent forward progress, - e.g., - by repeatedly stealing a cache line - for unrelated purposes - between load-locked and store-conditional instructions. - For implementations that follow this recommendation and - ensure that such effects cannot indefinitely delay progress - under expected operating conditions, - such anomalies - can therefore safely be ignored by programmers. - Outside this document, - this property is sometimes termed lock-free. - \end{note} -\end{itemize} - -\pnum -During the execution of a thread of execution, each of the following is termed -an \defn{execution step}: -\begin{itemize} -\item termination of the thread of execution, -\item performing an access through a volatile glvalue, or -\item completion of a call to a library I/O function, a - synchronization operation, or an atomic operation. -\end{itemize} +\begin{example} +Because each referenced namespace is searched at most once, the +following is well-defined: +\begin{codeblock} +namespace B { + int b; +} -\pnum -An invocation of a standard library function that blocks\iref{defns.block} -is considered to continuously execute execution steps while waiting for the -condition that it blocks on to be satisfied. -\begin{example} -A library I/O function that blocks until the I/O operation is complete can -be considered to continuously check whether the operation is complete. Each -such check consists of one or more execution steps, for example using -observable behavior of the abstract machine. +namespace A { + using namespace B; + int a; +} + +namespace B { + using namespace A; +} + +void f() +{ + A::a++; // OK, \tcode{a} declared directly in \tcode{A}, \tcode{S} is $\{ \tcode{A::a} \}$ + B::a++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{A::a} \}$ + A::b++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{B::b} \}$ + B::b++; // OK, \tcode{b} declared directly in \tcode{B}, \tcode{S} is $\{ \tcode{B::b} \}$ +} +\end{codeblock} \end{example} \pnum \begin{note} -Because of this and the preceding requirement regarding what threads of execution -have to perform eventually, it follows that no thread of execution can execute -forever without an execution step occurring. +Class and enumeration declarations are not discarded +because of other declarations found in other searches. \end{note} +\begin{example} +\begin{codeblock} +namespace A { + struct x { }; + int x; + int y; +} -\pnum -A thread of execution \defnx{makes progress}{make progress!thread} -when an execution step occurs or a -lock-free execution does not complete because there are other concurrent threads -that are not blocked in a standard library function (see above). +namespace B { + struct y { }; +} -\pnum -\indextext{forward progress guarantees!concurrent}% -For a thread of execution providing \defn{concurrent forward progress guarantees}, -the implementation ensures that the thread will eventually make progress for as -long as it has not terminated. -\begin{note} -This applies regardless of whether or not other threads of execution (if any) -have been or are making progress. To eventually fulfill this requirement means that -this will happen in an unspecified but finite amount of time. -\end{note} +namespace C { + using namespace A; + using namespace B; + int i = C::x; // OK, \tcode{A::x} (of type \tcode{int}) + int j = C::y; // ambiguous, \tcode{A::y} or \tcode{B::y} +} +\end{codeblock} +\end{example} -\pnum -It is \impldef{whether the thread that executes \tcode{main} and the threads created -by \tcode{std::thread} or \tcode{std::jthread} provide concurrent forward progress guarantees} whether the -implementation-created thread of execution that executes -\tcode{main}\iref{basic.start.main} and the threads of execution created by -\tcode{std::thread}\iref{thread.thread.class} -or \tcode{std::jthread}\iref{thread.jthread.class} -provide concurrent forward progress guarantees. -General-purpose implementations should provide these guarantees. +\indextext{lookup!qualified name|)}% -\pnum -\indextext{forward progress guarantees!parallel}% -For a thread of execution providing \defn{parallel forward progress guarantees}, -the implementation is not required to ensure that the thread will eventually make -progress if it has not yet executed any execution step; once this thread has -executed a step, it provides concurrent forward progress guarantees. +\rSec2[basic.lookup.elab]{Elaborated type specifiers}% +\indextext{lookup!elaborated type specifier|(}% +\indextext{type specifier!elaborated} \pnum +If the \grammarterm{class-key} or \keyword{enum} keyword +in an \grammarterm{elaborated-type-specifier} +is followed by an \grammarterm{identifier} +that is not followed by \tcode{::}, +lookup for the \grammarterm{identifier} is type-only\iref{basic.lookup.general}. \begin{note} -This does not specify a requirement for when to start this thread of execution, -which will typically be specified by the entity that creates this thread of -execution. For example, a thread of execution that provides concurrent forward -progress guarantees and executes tasks from a set of tasks in an arbitrary order, -one after the other, satisfies the requirements of parallel forward progress for -these tasks. +In general, the recognition of an \grammarterm{elaborated-type-specifier} +depends on the following tokens. +If the \grammarterm{identifier} is followed by \tcode{::}, +see \ref{basic.lookup.qual}. \end{note} \pnum -\indextext{forward progress guarantees!weakly parallel}% -For a thread of execution providing \defn{weakly parallel forward progress -guarantees}, the implementation does not ensure that the thread will eventually -make progress. +If the terminal name of the \grammarterm{elaborated-type-specifier} +is a qualified name, +lookup for it is type-only. +If the name lookup does not find a previously declared \grammarterm{type-name}, +the \grammarterm{elaborated-type-specifier} is ill-formed. \pnum -\begin{note} -Threads of execution providing weakly parallel forward progress guarantees cannot -be expected to make progress regardless of whether other threads make progress or -not; however, blocking with forward progress guarantee delegation, as defined below, -can be used to ensure that such threads of execution make progress eventually. -\end{note} +\begin{example} +\begin{codeblock} +struct Node { + struct Node* Next; // OK, refers to injected-class-name \tcode{Node} + struct Data* Data; // OK, declares type \tcode{Data} at global scope and member \tcode{Data} +}; -\pnum -Concurrent forward progress guarantees are stronger than parallel forward progress -guarantees, which in turn are stronger than weakly parallel forward progress -guarantees. -\begin{note} -For example, some kinds of synchronization between threads of execution might only -make progress if the respective threads of execution provide parallel forward progress -guarantees, but will fail to make progress under weakly parallel guarantees. -\end{note} +struct Data { + struct Node* Node; // OK, refers to \tcode{Node} at global scope + friend struct ::Glob; // error: \tcode{Glob} is not declared, cannot introduce a qualified type\iref{dcl.type.elab} + friend struct Glob; // OK, refers to (as yet) undeclared \tcode{Glob} at global scope. + @\commentellip@ +}; -\pnum -\indextext{forward progress guarantees!delegation of}% -When a thread of execution $P$ is specified to -\defnx{block with forward progress guarantee delegation} -{block (execution)!with forward progress guarantee delegation} -on the completion of a set $S$ of threads of execution, -then throughout the whole time of $P$ being blocked on $S$, -the implementation shall ensure that the forward progress guarantees -provided by at least one thread of execution in $S$ -is at least as strong as $P$'s forward progress guarantees. -\begin{note} -It is unspecified which thread or threads of execution in $S$ are chosen -and for which number of execution steps. The strengthening is not permanent and -not necessarily in place for the rest of the lifetime of the affected thread of -execution. As long as $P$ is blocked, the implementation has to eventually -select and potentially strengthen a thread of execution in $S$. -\end{note} -Once a thread of execution in $S$ terminates, it is removed from $S$. -Once $S$ is empty, $P$ is unblocked. +struct Base { + struct Data; // OK, declares nested \tcode{Data} + struct ::Data* thatData; // OK, refers to \tcode{::Data} + struct Base::Data* thisData; // OK, refers to nested \tcode{Data} + friend class ::Data; // OK, global \tcode{Data} is a friend + friend class Data; // OK, nested \tcode{Data} is a friend + struct Data { @\commentellip@ }; // Defines nested \tcode{Data} +}; -\pnum -\begin{note} -A thread of execution $B$ thus can temporarily provide an effectively -stronger forward progress guarantee for a certain amount of time, due to a -second thread of execution $A$ being blocked on it with forward -progress guarantee delegation. In turn, if $B$ then blocks with -forward progress guarantee delegation on $C$, this can also temporarily -provide a stronger forward progress guarantee to $C$. -\end{note} +struct Data; // OK, redeclares \tcode{Data} at global scope +struct ::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} +struct Base::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} +struct Base::Datum; // error: \tcode{Datum} undefined +struct Base::Data* pBase; // OK, refers to nested \tcode{Data} +\end{codeblock} +\end{example} +\indextext{lookup!elaborated type specifier|)}% -\pnum -\begin{note} -If all threads of execution in $S$ finish executing (e.g., they terminate -and do not use blocking synchronization incorrectly), then $P$'s execution -of the operation that blocks with forward progress guarantee delegation will not -result in $P$'s progress guarantee being effectively weakened. -\end{note} +\rSec2[basic.lookup.udir]{Using-directives and namespace aliases} \pnum -\begin{note} -This does not remove any constraints regarding blocking synchronization for -threads of execution providing parallel or weakly parallel forward progress -guarantees because the implementation is not required to strengthen a particular -thread of execution whose too-weak progress guarantee is preventing overall progress. -\end{note} +\indextext{lookup!using-directives and}% +\indextext{lookup!namespace aliases and}% +In a \grammarterm{using-directive} or \grammarterm{namespace-alias-definition}, +during the lookup for a \grammarterm{namespace-name} or for a name in a +\grammarterm{nested-name-specifier}{} +only namespace names are considered.% +\indextext{lookup!name|)}% -\pnum -An implementation should ensure that the last value (in modification order) -assigned by an atomic or synchronization operation will become visible to all -other threads in a finite period of time.% -\indextext{atomic!operation|)}% -\indextext{threads!multiple|)} +\rSec1[basic.def.odr]{One-definition rule}% +\indextext{object!definition}% +\indextext{function!definition}% +\indextext{class!definition}% +\indextext{enumerator!definition}% +\indextext{one-definition rule|(}% -\rSec2[basic.start]{Start and termination} +\pnum +Each of the following is termed a \defnadj{definable}{item}: +\begin{itemize} +\item a variable\iref{basic.link}, +\item a function\iref{dcl.fct}, +\item a default argument for a parameter +(for a function in a given scope)\iref{dcl.fct.default}, or +\item an enumeration type\iref{dcl.enum}, +\item a class type\iref{class}, +\item a templated entity\iref{temp.pre}, +\item a default template argument\iref{temp.param}. +\end{itemize} -\rSec3[basic.start.main]{\tcode{main} function} -\indextext{\idxcode{main} function|(} +\pnum +No translation unit shall contain more than one definition of any +definable item. \pnum -\indextext{program!startup|(}% -A program shall contain exactly one function called \tcode{main} -that belongs to the global scope. -Executing a program starts a main thread of execution\iref{intro.multithread,thread.threads} -in which the \tcode{main} function is invoked. -\indextext{implementation!freestanding}% -It is \impldef{defining \tcode{main} in freestanding environment} -whether a program in a freestanding environment is required to define a \tcode{main} -function. +\indextext{expression!potentially evaluated}% +An expression or conversion is \defn{potentially evaluated} unless it is +an unevaluated operand\iref{expr.context}, +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 $E$ is +defined as follows: +\begin{itemize} +\item If $E$ is an +\grammarterm{id-expression}\iref{expr.prim.id}, the set +contains only $E$. +\item If $E$ is a subscripting operation\iref{expr.sub} with +an array operand, the set contains the potential results of that operand. +\item If $E$ is a class member access +expression\iref{expr.ref} of the form +$E_1$ \tcode{.} \opt{\keyword{template}} $E_2$ +naming a non-static data member, +the set contains the potential results of $E_1$. +\item If $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 $E$ is a pointer-to-member +expression\iref{expr.mptr.oper} of the form +$E_1$ \tcode{.*} $E_2$, +the set contains the potential results of $E_1$. +\item If $E$ has the form \tcode{($E_1$)}, the set contains the +potential results of $E_1$. +\item If $E$ is a glvalue conditional +expression\iref{expr.cond}, the set is the union of the sets of +potential results of the second and third operands. +\item If $E$ is a comma expression\iref{expr.comma}, the set +contains the potential results of the right operand. +\item Otherwise, the set is empty. +\end{itemize} \begin{note} -In a freestanding environment, startup and termination is -\impldef{startup and termination in freestanding environment}; startup contains the -execution of constructors for non-local objects with static storage duration; -termination contains the execution of destructors for objects with static storage -duration. +This set is a (possibly-empty) set of \grammarterm{id-expression}{s}, +each of which is either $E$ or a subexpression of $E$. +\begin{example} +In the following example, the set of potential results of the initializer +of \tcode{n} contains the first \tcode{S::x} subexpression, but not the second +\tcode{S::x} subexpression. +\begin{codeblock} +struct S { static const int x = 0; }; +const int &f(const int &r); +int n = b ? (1, S::x) // \tcode{S::x} is not odr-used here + : f(S::x); // \tcode{S::x} is odr-used here, so a definition is required +\end{codeblock} +\end{example} \end{note} \pnum -An implementation shall not predefine the \tcode{main} function. -Its type shall have \Cpp{} language linkage -and it shall have a declared return type of type -\keyword{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. -\indextext{\idxcode{main} function!implementation-defined parameters to}% -An implementation shall allow both +A function is \defnx{named by}{function!named by expression or conversion} +an expression or conversion as follows: \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 + A function is named by an expression or conversion + if it is the selected member + of an overload set\iref{basic.lookup,over.match,over.over} + in an overload resolution performed + as part of forming that expression or conversion, + unless it is a pure virtual function and either + 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\iref{conv.func,expr.unary.op}, + calls to named functions\iref{expr.call}, + operator overloading\iref{over}, + user-defined conversions\iref{class.conv.fct}, + 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 or conversion + even if the call is actually elided by the implementation\iref{class.copy.elision}. +\end{note} +\item + A deallocation function for a class + is named by a \grammarterm{new-expression} + 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 \grammarterm{delete-expression} + if it is the selected usual deallocation function + as specified in~\ref{expr.delete} and~\ref{class.free}. \end{itemize} -\indextext{\idxcode{argc}}% -\indextext{\idxcode{argv}}% -as the type of \tcode{main}\iref{dcl.fct}. -\indextext{\idxcode{main} function!parameters to}% -\indextext{environment!program}% -In the latter form, for purposes of exposition, the first function -parameter is called \tcode{argc} and the second function parameter is -called \tcode{argv}, where \tcode{argc} shall be the number of -arguments passed to the program from the environment in which the -program is run. If -\tcode{argc} is nonzero these arguments shall be supplied in -\tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial -characters of null-terminated multibyte strings (\ntmbs{}s)\iref{multibyte.strings} -and \tcode{argv[0]} shall be the pointer to -the initial character of an \ntmbs{} that represents the name used to -invoke the program or \tcode{""}. The value of \tcode{argc} shall be -non-negative. The value of \tcode{argv[argc]} shall be 0. - -\recommended -Any further (optional) parameters should be added after \tcode{argv}. \pnum -The function \tcode{main} shall not be named by an expression. -\indextext{\idxcode{main} function!implementation-defined linkage of}% -The linkage\iref{basic.link} of \tcode{main} is -\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as -deleted or that declares \tcode{main} to be -\keyword{inline}, \keyword{static}, \keyword{constexpr}, or \keyword{consteval} is ill-formed. -The function \tcode{main} shall not be a coroutine\iref{dcl.fct.def.coroutine}. -The \tcode{main} function shall not be declared with a -\grammarterm{linkage-specification}\iref{dcl.link}. -A program that declares +\label{term.odr.use}% +A variable is named by an expression +if the expression is an \grammarterm{id-expression} that denotes it. +A variable \tcode{x} that is named by a +potentially-evaluated expression $E$ +is \defnx{odr-used}{odr-use} by $E$ unless \begin{itemize} \item -a variable \tcode{main} that belongs to the global scope, or -\item -a function \tcode{main} that belongs to the global scope and -is attached to a named module, or + \tcode{x} is a reference that is + usable in constant expressions\iref{expr.const}, or \item -a function template \tcode{main} that belongs to the global scope, or + \tcode{x} is a variable of non-reference type that is + usable in constant expressions and has no mutable subobjects, and + $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 -an entity named \tcode{main} -with C language linkage (in any namespace) + \tcode{x} is a variable of non-reference type, and + $E$ is an element of the set of potential results + of a discarded-value expression\iref{expr.context} + to which the lvalue-to-rvalue conversion is not applied. \end{itemize} -is ill-formed. -The name \tcode{main} is -not otherwise reserved. -\begin{example} -Member functions, classes, and -enumerations can be called \tcode{main}, as can entities in other -namespaces. -\end{example} \pnum -\indextext{\idxcode{exit}}% -\indexlibraryglobal{exit}% -\indextext{termination!program}% -Terminating the program -without leaving the current block (e.g., by calling the function -\tcode{std::exit(int)}\iref{support.start.term}) does not destroy any -objects with automatic storage duration\iref{class.dtor}. If -\tcode{std::exit} is invoked during the destruction of -an object with static or thread storage duration, the program has undefined -behavior. +A structured binding is odr-used if it appears as a potentially-evaluated expression. \pnum -\indextext{termination!program}% -\indextext{\idxcode{main} function!return from}% -A \keyword{return} statement\iref{stmt.return} in \tcode{main} has the effect of leaving the main -function (destroying any objects with automatic storage duration) and -calling \tcode{std::exit} with the return value as the argument. -If control flows off the end of -the \grammarterm{compound-statement} of \tcode{main}, -the effect is equivalent to a \keyword{return} with operand \tcode{0} -(see also \ref{except.handle}). -\indextext{\idxcode{main} function|)} +\tcode{*\keyword{this}} is odr-used if \keyword{this} appears as a potentially-evaluated expression +(including as the result of any implicit transformation to +a class member access expression\iref{expr.prim.id.general}). -\rSec3[basic.start.static]{Static initialization} +\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 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 +definition of the destructor of that class, or by being selected by the +lookup at the point of definition of a virtual +destructor\iref{class.dtor}. +\begin{footnote} +An implementation is not required +to call allocation and +deallocation functions from constructors or destructors; however, this +is a permissible implementation technique. +\end{footnote} \pnum -\indextext{initialization}% -\indextext{initialization!static and thread}% -Variables with static storage duration -are initialized as a consequence of program initiation. Variables with -thread storage duration are initialized as a consequence of thread execution. -Within each of these phases of initiation, initialization occurs as follows. +An assignment operator function in a class is odr-used by an +implicitly-defined +copy assignment or move assignment function for another class as specified +in~\ref{class.copy.assign}. +A constructor for a class is odr-used as specified +in~\ref{dcl.init}. A destructor for a class is odr-used if it is potentially +invoked\iref{class.dtor}. \pnum -\indextext{initialization!constant}% -\defnx{Constant initialization}{constant initialization} is performed -if a variable or temporary object with static or thread storage duration -is constant-initialized\iref{expr.const}. -\indextext{initialization!zero-initialization}% -If constant initialization is not performed, a variable with static -storage duration\iref{basic.stc.static} or thread storage -duration\iref{basic.stc.thread} is zero-initialized\iref{dcl.init}. -Together, zero-initialization and constant initialization are called -\defnadj{static}{initialization}; -all other initialization is \defnadj{dynamic}{initialization}. -All static initialization strongly happens before\iref{intro.races} -any dynamic initialization. -\begin{note} -The dynamic initialization of non-block variables is described -in~\ref{basic.start.dynamic}; that of static block variables is described -in~\ref{stmt.dcl}. -\end{note} +A \defnadj{local}{entity} is a variable with +automatic storage duration\iref{basic.stc.auto}, +a structured binding\iref{dcl.struct.bind} +whose corresponding variable is such an entity, +or the \tcode{*\keyword{this}} object\iref{expr.prim.this}. + +\pnum +A local entity +is \defn{odr-usable} in a scope\iref{basic.scope.scope} if +\begin{itemize} +\item either the local entity is not \tcode{*\keyword{this}}, or +an enclosing class or non-lambda function parameter scope exists and, +if the innermost such scope is a function parameter scope, +it corresponds to a non-static member function, and +\item +for each intervening scope\iref{basic.scope.scope} +between the point at which the entity is introduced and the scope +(where \tcode{*\keyword{this}} is considered to be introduced +within the innermost enclosing class or non-lambda function definition scope), +either: +\begin{itemize} +\item the intervening scope is a block scope, or +\item the intervening scope is the function parameter scope of a \grammarterm{lambda-expression}, or +\item the intervening scope is the lambda scope of +a \grammarterm{lambda-expression} +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 scope. +\end{itemize} +\end{itemize} + +If a local entity is odr-used +in a scope in which it is not odr-usable, +the program is ill-formed. +\begin{example} +\begin{codeblock} +void f(int n) { + [] { 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 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} +\end{example} \pnum -An implementation is permitted to perform the initialization of a -variable with static or thread storage duration as a static -initialization even if such initialization is not required to be done -statically, provided that -\begin{itemize} -\item -the dynamic version of the initialization does not change the -value of any other object of static or thread storage duration -prior to its initialization, and - -\item -the static version of the initialization produces the same value -in the initialized variable as would be produced by the dynamic -initialization if all variables not required to be initialized statically -were initialized dynamically. -\end{itemize} -\begin{note} -As a consequence, if the initialization of an object \tcode{obj1} refers to an -object \tcode{obj2} potentially requiring dynamic initialization and defined -later in the same translation unit, it is unspecified whether the value of \tcode{obj2} used -will be the value of the fully initialized \tcode{obj2} (because \tcode{obj2} was statically -initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example, +\begin{example} \begin{codeblock} -inline double fd() { return 1.0; } -extern double d1; -double d2 = d1; // unspecified: - // either statically initialized to \tcode{0.0} or - // dynamically initialized to \tcode{0.0} if \tcode{d1} is - // dynamically initialized, or \tcode{1.0} otherwise -double d1 = fd(); // either initialized statically or dynamically to \tcode{1.0} +void g() { + constexpr int x = 1; + auto lambda = [] {}; // OK + lambda.operator()(); // OK, does not consider \tcode{x} at all + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} + +void h() { + constexpr int x = 1; + auto lambda = [] { (T)x; }; // OK + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} \end{codeblock} -\end{note} +\end{example} -\rSec3[basic.start.dynamic]{Dynamic initialization of non-block variables} +\pnum +Every program shall contain at least one definition of every +function or variable that is odr-used in that program +outside of a discarded statement\iref{stmt.if}; no diagnostic required. +The definition can appear explicitly in the program, it can be found in +the standard or a user-defined library, or (when appropriate) it is +implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor}, +\ref{class.dtor}, and \ref{class.copy.assign}). +\begin{example} +\begin{codeblock} +auto f() { + struct A {}; + return A{}; +} +decltype(f()) g(); +auto x = g(); +\end{codeblock} +A program containing this translation unit is ill-formed +because \tcode{g} is odr-used but not defined, +and cannot be defined in any other translation unit +because the local class \tcode{A} cannot be named outside this +translation unit. +\end{example} \pnum -\indextext{initialization!dynamic non-block}% -\indextext{start!program}% -\indextext{initialization!order of}% -Dynamic initialization of a non-block variable with static storage duration is -unordered if the variable is an implicitly or explicitly instantiated -specialization, is partially-ordered if the variable -is an inline variable that is not an implicitly or explicitly instantiated -specialization, and otherwise is ordered. -\begin{note} -A non-inline explicit specialization of a templated variable -has ordered initialization. -\end{note} +A \defn{definition domain} is +a \grammarterm{private-module-fragment} or +the portion of a translation unit +excluding its \grammarterm{private-module-fragment} (if any). +A definition of an inline function or variable shall be reachable +from the end of every definition domain +in which it is odr-used outside of a discarded statement. \pnum -A declaration \tcode{D} is -\defn{appearance-ordered} before a declaration \tcode{E} if +\indextext{type!incomplete}% +A definition of a class shall be reachable in every context in which +the class is used in a way that requires the class type to be complete. +\begin{example} +The following complete translation unit is well-formed, +even though it never defines \tcode{X}: +\begin{codeblock} +struct X; // declare \tcode{X} as a struct type +struct X* x1; // use \tcode{X} in pointer formation +X* x2; // use \tcode{X} in pointer formation +\end{codeblock} +\end{example} +\begin{note} +The rules for declarations and expressions +describe in which contexts complete class types are required. A class +type \tcode{T} must be complete if \begin{itemize} -\item \tcode{D} appears in the same translation unit as \tcode{E}, or -\item the translation unit containing \tcode{E} -has an interface dependency on the translation unit containing \tcode{D}, +\item an object of type \tcode{T} is defined\iref{basic.def}, or +\item a function with a return type or argument type of type \tcode{T} +is defined\iref{basic.def} or called\iref{expr.call}, or +\item the type \tcode{T} is the subject of an +\keyword{alignof} expression\iref{expr.alignof}, or +\item \tcode{T} is used as the allocated type or array element type in a +\grammarterm{new-expression}\iref{expr.new}, or +\item an expression is converted (either implicitly or explicitly) to +type \tcode{T}\iref{conv,expr.type.conv, +expr.dynamic.cast,expr.static.cast,expr.cast}, or +\item an expression that is not a null pointer constant, and has type +other than \cv{}~\tcode{\keyword{void}*}, is converted to the type pointer to \tcode{T} +or reference to \tcode{T} using a standard conversion\iref{conv}, +a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or +a \keyword{static_cast}\iref{expr.static.cast}, or +\item an lvalue-to-rvalue conversion is applied to +a glvalue referring +to an object of type \tcode{T}\iref{conv.lval}, or +\item a class member access operator is applied to an expression of type +\tcode{T}\iref{expr.ref}, or +\item the \keyword{typeid} operator\iref{expr.typeid} or the +\keyword{sizeof} operator\iref{expr.sizeof} is applied to an operand of +type \tcode{T}, or +\item an lvalue of type \tcode{T} is assigned to\iref{expr.ass}, or +\item an \grammarterm{exception-declaration} has type \tcode{T}, reference to +\tcode{T}, or pointer to \tcode{T}\iref{except.handle}, or +\item a non-static class data member of type \tcode{T} is +declared\iref{class.mem}, or +\item a class with a base class of type \tcode{T} is +defined\iref{class.derived}. \end{itemize} -in either case prior to \tcode{E}. +\end{note} \pnum -Dynamic initialization of non-block variables \tcode{V} and \tcode{W} -with static storage duration are ordered as follows: -\begin{itemize} -\item -If \tcode{V} and \tcode{W} have ordered initialization and -the definition of \tcode{V} -is appearance-ordered before the definition of \tcode{W}, or -if \tcode{V} has partially-ordered initialization, -\tcode{W} does not have unordered initialization, and -for every definition \tcode{E} of \tcode{W} -there exists a definition \tcode{D} of \tcode{V} -such that \tcode{D} is appearance-ordered before \tcode{E}, then +For any definable item \tcode{D} with definitions in multiple translation units, \begin{itemize} \item -if the program does not start a thread\iref{intro.multithread} -other than the main thread\iref{basic.start.main} -or \tcode{V} and \tcode{W} have ordered initialization and -they are defined in the same translation unit, -the initialization of \tcode{V} -is sequenced before -the initialization of \tcode{W}; +if \tcode{D} is a non-inline non-templated function or variable, or \item -otherwise, -the initialization of \tcode{V} -strongly happens before -the initialization of \tcode{W}. +if the definitions in different translation units +do not satisfy the following requirements, \end{itemize} - -\item -Otherwise, if the program starts a thread -other than the main thread -before either \tcode{V} or \tcode{W} is initialized, -it is unspecified in which threads -the initializations of \tcode{V} and \tcode{W} occur; -the initializations are unsequenced if they occur in the same thread. - +the program is ill-formed; +a diagnostic is required only +if the definable item is attached to a named module and +a prior definition is reachable at the point where a later definition occurs. +Given such an item, +for all definitions of \tcode{D}, or, +if \tcode{D} is an unnamed enumeration, +for all definitions of \tcode{D} that are reachable at any given program point, +the following requirements shall be satisfied. +\begin{itemize} +\item Each such definition +shall not be attached to a named module\iref{module.unit}. +\item Each such definition shall consist of +the same sequence of tokens, +where the definition of a closure type +is considered to consist of the sequence of tokens of +the corresponding \grammarterm{lambda-expression}. +\item In each such definition, corresponding names, looked up +according to~\ref{basic.lookup}, shall refer to the same entity, after +overload resolution\iref{over.match} and after matching of partial +template specialization\iref{temp.over}, except that a name can refer to +\begin{itemize} \item -Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced. +a non-volatile const object with internal or no linkage if the object +\begin{itemize} +\item has the same literal type in all definitions of \tcode{D}, +\item is initialized with a constant expression\iref{expr.const}, +\item is not odr-used in any definition of \tcode{D}, and +\item has the same value in all definitions of \tcode{D}, +\end{itemize} +or +\item +a reference with internal or no linkage +initialized with a constant expression such that +the reference refers to the same entity in all definitions of \tcode{D}. \end{itemize} -\begin{note} -This definition permits initialization of a sequence of -ordered variables concurrently with another sequence. -\end{note} - -\pnum -\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% -A \defnx{non-initialization odr-use}{odr-use!non-initialization} -is an odr-use\iref{term.odr.use} not caused directly or indirectly by -the initialization of a non-block static or thread storage duration variable. - -\pnum -\indextext{evaluation!unspecified order of}% -It is \impldef{dynamic initialization of static variables before \tcode{main}} -whether the dynamic initialization of a -non-block non-inline variable with static storage duration -is sequenced before the first statement of \tcode{main} or is deferred. -If it is deferred, it strongly happens before -any non-initialization odr-use -of any non-inline function or non-inline variable -defined in the same translation unit as the variable to be initialized. -\begin{footnote} -A non-block variable with static storage duration -having initialization -with side effects is initialized in this case, -even if it is not itself odr-used\iref{term.odr.use,basic.stc.static}. -\end{footnote} -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. - -\recommended -An implementation should choose such points in a way -that allows the programmer to avoid deadlocks. -\begin{example} -\begin{codeblock} -// - File 1 - -#include "a.h" -#include "b.h" -B b; -A::A() { - b.Use(); -} -// - File 2 - -#include "a.h" -A a; +\item In each such definition, except within +the default arguments and default template arguments of \tcode{D}, +corresponding \grammarterm{lambda-expression}{s} shall have +the same closure type (see below). -// - File 3 - -#include "a.h" -#include "b.h" -extern A a; -extern B b; +\item In each such definition, corresponding entities shall have the +same language linkage. -int main() { - a.Use(); - b.Use(); -} -\end{codeblock} +\item In each such definition, +const objects with static or thread storage duration +shall be constant-initialized if +the object is constant-initialized in any such definition. -It is \impldef{dynamic initialization of static variables before \tcode{main}} -whether either \tcode{a} or \tcode{b} is -initialized before \tcode{main} is entered or whether the -initializations are delayed until \tcode{a} is first odr-used in -\tcode{main}. In particular, if \tcode{a} is initialized before -\tcode{main} is entered, it is not guaranteed that \tcode{b} will be -initialized before it is odr-used by the initialization of \tcode{a}, that -is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized -at some point after the first statement of \tcode{main}, \tcode{b} will -be initialized prior to its use in \tcode{A::A}. -\end{example} +\item In each such definition, +corresponding manifestly constant-evaluated expressions +that are not value-dependent +shall have the same value\iref{expr.const,temp.dep.constexpr}. -\pnum -It is \impldef{dynamic initialization of static inline variables before \tcode{main}} -whether the dynamic initialization of a -non-block inline variable with static storage duration -is sequenced before the first statement of \tcode{main} or is deferred. -If it is deferred, it strongly happens before -any non-initialization odr-use -of that variable. -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. +\item In each such definition, the overloaded operators referred +to, the implicit calls to conversion functions, constructors, operator +new functions and operator delete functions, shall refer to the same +function. -\pnum -It is \impldef{dynamic initialization of thread-local variables before entry} -whether the dynamic initialization of a -non-block non-inline variable with thread storage duration -is sequenced before the first statement of the initial function of a thread or is deferred. -If it is deferred, -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 -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. +\item In each such definition, +a default argument used by an (implicit or explicit) function call or +a default template argument used by an (implicit or explicit) +\grammarterm{template-id} or \grammarterm{simple-template-id} +is treated as if its token sequence +were present in the definition of \tcode{D}; +that is, the default argument or default template argument +is subject to the requirements described in this paragraph (recursively). +\end{itemize} \pnum -If the initialization of -a non-block variable with static or thread storage duration -exits via an exception, -the function \tcode{std::terminate} is called\iref{except.terminate}.% -\indextext{program!startup|)} +For the purposes of the preceding requirements: -\rSec3[basic.start.term]{Termination} +\begin{itemize} +\item If \tcode{D} is a class with an implicitly-declared +constructor\iref{class.default.ctor,class.copy.ctor}, +it is as if the constructor was +implicitly defined in every translation unit where it is odr-used, and the +implicit definition in every translation unit shall call the same +constructor for a subobject of \tcode{D}. +\begin{example} +\begin{codeblock} +// translation unit 1: +struct X { + X(int, int); + X(int, int, int); +}; +X::X(int, int = 0) { } +class D { + X x = 0; +}; +D d1; // \tcode{X(int, int)} called by \tcode{D()} -\pnum -\indextext{program!termination|(}% -\indextext{object!destructor static}% -\indextext{\idxcode{main} function!return from}% -Constructed 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 -\indextext{\idxcode{exit}}% -\indexlibraryglobal{exit}% -\tcode{std::exit}\iref{support.start.term}. -The call to \tcode{std::exit} is sequenced before -the destructions and the registered functions. -\begin{note} -Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. -\end{note} +// translation unit 2: +struct X { + X(int, int); + X(int, int, int); +}; +X::X(int, int = 0, int = 0) { } +class D { + X x = 0; +}; +D d2; // \tcode{X(int, int, int)} called by \tcode{D()}; + // \tcode{D()}'s implicit definition violates the ODR +\end{codeblock} +\end{example} -\pnum -Constructed 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 -any object with static storage duration. +\item If \tcode{D} is a class with +a defaulted three-way comparison operator function\iref{class.spaceship}, +it is as if the operator was +implicitly defined in every translation unit where it is odr-used, and the +implicit definition in every translation unit shall call the same +comparison operators for each subobject of \tcode{D}. -\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. -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. -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}. +\item +If \tcode{D} is a template and is defined in more than one +translation unit, the requirements +apply both to names from the template's enclosing scope used in the +template definition, and also to dependent names at +the point of instantiation\iref{temp.dep}. +\end{itemize} \pnum -If a function contains a block variable of static or thread storage duration that has been -destroyed and the function is called during the destruction of an object with static or -thread storage duration, the program has undefined behavior if the flow of control -passes through the definition of the previously destroyed block variable. +These requirements also apply to corresponding entities +defined within each definition of \tcode{D} +(including the closure types of \grammarterm{lambda-expression}{s}, +but excluding entities defined within default arguments or +default template arguments of either \tcode{D} or +an entity not defined within \tcode{D}). +For each such entity and for \tcode{D} itself, +the behavior is as if there is a single entity with a single definition, +including in the application of these requirements to other entities. \begin{note} -Likewise, the behavior is undefined -if the block variable is used indirectly (e.g., through a pointer) -after its destruction. +The entity is still declared in multiple translation units, and \ref{basic.link} +still applies to these declarations. In particular, +\grammarterm{lambda-expression}{s}\iref{expr.prim.lambda} +appearing in the type of \tcode{D} can result +in the different declarations having distinct types, and +\grammarterm{lambda-expression}{s} appearing in a default argument of \tcode{D} +might still denote different types in different translation units. \end{note} \pnum -\indextext{\idxcode{atexit}}% -\indexlibraryglobal{atexit}% -If the completion of the initialization of an 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 -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 -the call to the function passed to the first \tcode{std::atexit} call. +\begin{example} +\begin{codeblock} +inline void f(bool cond, void (*p)()) { + if (cond) f(false, []{}); +} +inline void g(bool cond, void (*p)() = []{}) { + if (cond) g(false); +} +struct X { + void h(bool cond, void (*p)() = []{}) { + if (cond) h(false); + } +}; +\end{codeblock} -\pnum -If there is a use of a standard library object or function not permitted within signal -handlers\iref{support.runtime} that does not happen before\iref{intro.multithread} -completion of destruction of objects with static storage duration and execution of -\tcode{std::atexit} registered functions\iref{support.start.term}, the program has -undefined behavior. -\begin{note} -If there is a use of an object with static storage -duration that does not happen before the object's destruction, the program has undefined -behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from -\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These -requirements permit thread managers as static-storage-duration objects. -\end{note} +If the definition of \tcode{f} appears in multiple translation units, +the behavior of the program is as if +there is only one definition of \tcode{f}. +If the definition of \tcode{g} appears in multiple translation units, +the program is ill-formed (no diagnostic required) because +each such definition uses a default argument that +refers to a distinct \grammarterm{lambda-expression} closure type. +The definition of \tcode{X} can appear +in multiple translation units of a valid program; +the \grammarterm{lambda-expression}{s} defined within +the default argument of \tcode{X::h} within the definition of \tcode{X} +denote the same closure type in each translation unit. +\end{example} \pnum -\indextext{\idxcode{abort}}% -\indexlibraryglobal{abort}% -\indextext{termination!program}% -Calling the function \tcode{std::abort()} declared in -\libheaderref{cstdlib} terminates the program without executing any destructors -and without calling -the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% -\indextext{program!termination|)} -\indextext{program execution|)} +If, at any point in the program, +there is more than one +reachable unnamed enumeration definition in the same scope +that have the same first enumerator name and +do not have typedef names for linkage purposes\iref{dcl.enum}, +those unnamed enumeration types shall be the same; no diagnostic required. +\indextext{one-definition rule|)} diff --git a/source/compatibility.tex b/source/compatibility.tex index 93baac8554..8840243133 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -53,7 +53,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp23.dcl]{\ref{dcl}: declarations} \diffref{dcl.init.list} \change @@ -359,7 +359,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.stmt]{\ref{stmt.stmt}: statements} +\rSec2[diff.cpp20.stmt]{\ref{stmt}: statements} \diffref{stmt.ranged} \change @@ -383,7 +383,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp20.dcl]{\ref{dcl}: declarations} \diffref{dcl.init.string} \change @@ -850,7 +850,7 @@ if those entities are only referenced in contexts that do not result in an odr-use. -\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp17.dcl]{\ref{dcl}: declarations} \diffref{dcl.typedef} \change @@ -1489,7 +1489,7 @@ \tcode{::operator new(std::size_t, std::align_val_t)} is used instead. -\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp14.dcl]{\ref{dcl}: declarations} \diffref{dcl.stc} \indextext{\idxcode{register} storage class}% @@ -1875,7 +1875,7 @@ revision of \Cpp{}, it yields \tcode{sizeof(const char[1])}. \end{example} -\rSec2[diff.cpp11.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp11.dcl]{\ref{dcl}: declarations} \diffref{dcl.constexpr} \change @@ -2117,7 +2117,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp03.dcl]{\ref{dcl}: declarations} \diffref{dcl.spec} \change @@ -2923,7 +2923,7 @@ \howwide Rare. -\rSec2[diff.stat]{\ref{stmt.stmt}: statements} +\rSec2[diff.stmt]{\ref{stmt}: statements} \diffref{stmt.switch,stmt.goto} \change @@ -2971,7 +2971,7 @@ For several years, many existing C implementations have produced warnings in this case. -\rSec2[diff.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.dcl]{\ref{dcl}: declarations} \diffref{dcl.stc} \change diff --git a/source/config.tex b/source/config.tex index 990cc07b44..79b76aef5c 100644 --- a/source/config.tex +++ b/source/config.tex @@ -8,6 +8,10 @@ %% Release date \newcommand{\reldate}{\today} +%% Core chapters +\newcommand{\firstcorechapter}{lex} +\newcommand{\lastcorechapter}{temp} + %% Library chapters \newcommand{\firstlibchapter}{support} \newcommand{\lastlibchapter}{exec} diff --git a/source/declarations.tex b/source/declarations.tex index 446aebd3aa..12c59a9853 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1,5 +1,5 @@ %!TEX root = std.tex -\rSec0[dcl.dcl]{Declarations}% +\rSec0[dcl]{Declarations}% \indextext{declaration|(} \gramSec[gram.dcl]{Declarations} @@ -129,7 +129,7 @@ \indextext{scope}% Certain declarations contain one or more scopes\iref{basic.scope.scope}. Unless otherwise stated, utterances in -\ref{dcl.dcl} about components in, of, or contained by a +\ref{dcl} about components in, of, or contained by a declaration or subcomponent thereof refer only to those components of the declaration that are \emph{not} nested within scopes nested within the declaration. @@ -4422,6 +4422,273 @@ \indextext{declaration!default argument|)}% \indextext{declarator!meaning of|)} +\rSec3[except.spec]{Exception specifications}% +\indextext{exception specification|(} + +\pnum +The predicate indicating whether a function cannot exit via an exception +is called the \defn{exception specification} of the function. +If the predicate is false, +the function has a +\indextext{exception specification!potentially-throwing}% +\defnx{potentially-throwing exception specification}% +{potentially-throwing!exception specification}, +otherwise it has a +\indextext{exception specification!non-throwing}% +\defn{non-throwing exception specification}. +The exception specification is either defined implicitly, +or defined explicitly +by using a \grammarterm{noexcept-specifier} +as a suffix of a function declarator\iref{dcl.fct}. + +\begin{bnf} +\nontermdef{noexcept-specifier}\br + \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br + \keyword{noexcept}\br +\end{bnf} + +\pnum +\indextext{exception specification!noexcept!constant expression and}% +In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression}, +if supplied, shall be a contextually converted constant expression +of type \keyword{bool}\iref{expr.const}; +that constant expression is the exception specification of +the function type in which the \grammarterm{noexcept-specifier} appears. +A \tcode{(} token that follows \keyword{noexcept} is part of the +\grammarterm{noexcept-specifier} and does not commence an +initializer\iref{dcl.init}. +The \grammarterm{noexcept-specifier} \keyword{noexcept} +without a \grammarterm{constant-expression} +is +equivalent to the \grammarterm{noexcept-specifier} +\tcode{\keyword{noexcept}(\keyword{true})}. +\begin{example} +\begin{codeblock} +void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool} +void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing +\end{codeblock} +\end{example} + +\pnum +If a declaration of a function +does not have a \grammarterm{noexcept-specifier}, +the declaration has a potentially throwing exception specification +unless it is a destructor or a deallocation function +or is defaulted on its first declaration, +in which cases the exception specification +is as specified below +and no other declaration for that function +shall have a \grammarterm{noexcept-specifier}. +In an explicit instantiation\iref{temp.explicit} +a \grammarterm{noexcept-specifier} may be specified, +but is not required. +If a \grammarterm{noexcept-specifier} is specified +in an explicit instantiation, +the exception specification shall be the same as +the exception specification of all other declarations of that function. +A diagnostic is required only if the +exception specifications are not the same +within a single translation unit. + +\pnum +\indextext{exception specification!virtual function and}% +If a virtual function has a +non-throwing exception specification, +all declarations, including the definition, of any function +that overrides that virtual function in any derived class +shall have a non-throwing +exception specification, +unless the overriding function is defined as deleted. +\begin{example} +\begin{codeblock} +struct B { + virtual void f() noexcept; + virtual void g(); + virtual void h() noexcept = delete; +}; + +struct D: B { + void f(); // error + void g() noexcept; // OK + void h() = delete; // OK +}; +\end{codeblock} + +The declaration of +\tcode{D::f} +is ill-formed because it +has a potentially-throwing exception specification, +whereas +\tcode{B::f} +has a non-throwing exception specification. +\end{example} + +\pnum +An expression $E$ is +\defnx{potentially-throwing}{potentially-throwing!expression} if +\begin{itemize} +\item +$E$ is a \grammarterm{throw-expression}\iref{expr.throw}, +or +\item +$E$ implicitly invokes a function +(such as an overloaded operator, +an allocation function in a \grammarterm{new-expression}, +a constructor for a function argument, +or a destructor if $E$ is a full-expression\iref{intro.execution}) +that has a potentially-throwing exception specification, +or +\item +any of the immediate subexpressions\iref{intro.execution} +of $E$ is potentially-throwing, +or +\item +$E$ is a function call\iref{expr.call} +whose \grammarterm{postfix-expression} +has a function type, +or a pointer-to-function type, +with a potentially-throwing exception specification, +or +\item +$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and +requires a runtime check\iref{expr.dynamic.cast}, +or +\item +$E$ is a \keyword{typeid} expression applied to a +(possibly parenthesized) built-in unary \tcode{*} operator +applied to a pointer to a +polymorphic class type\iref{expr.typeid}. +\end{itemize} + +\pnum +An implicitly-declared constructor for a class \tcode{X}, +or a constructor without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration, +has a potentially-throwing exception specification +if and only if +any of the following constructs is potentially-throwing: +\begin{itemize} +\item +the invocation of a constructor selected by overload resolution +in the implicit definition of the constructor +for class \tcode{X} +to initialize a potentially constructed subobject, or +\item +a subexpression of such an initialization, +such as a default argument expression, or, +\item +for a default constructor, a default member initializer. +\end{itemize} +\begin{note} +Even though destructors for fully-constructed subobjects +are invoked when an exception is thrown +during the execution of a constructor\iref{except.ctor}, +their exception specifications do not contribute +to the exception specification of the constructor, +because an exception thrown from such a destructor +would call the function \tcode{std::terminate} +rather than escape the constructor\iref{except.throw,except.terminate}. +\end{note} + +\pnum +The exception specification for an implicitly-declared destructor, +or a destructor without a \grammarterm{noexcept-specifier}, +is potentially-throwing if and only if +any of the destructors +for any of its potentially constructed subobjects +has a potentially-throwing exception specification or +the destructor is virtual and the destructor of any virtual base class +has a potentially-throwing exception specification. + +\pnum +The exception specification for an implicitly-declared assignment operator, +or an assignment-operator without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration, +is potentially-throwing if and only if +the invocation of any assignment operator +in the implicit definition is potentially-throwing. + +\pnum +A deallocation function\iref{basic.stc.dynamic.deallocation} +with no explicit \grammarterm{noexcept-specifier} +has a non-throwing exception specification. + +\pnum +The exception specification for a comparison operator function\iref{over.binary} +without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration +is potentially-throwing if and only if +any expression +in the implicit definition is potentially-throwing. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + A(int = (A(5), 0)) noexcept; + A(const A&) noexcept; + A(A&&) noexcept; + ~A(); +}; +struct B { + B() noexcept; + B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})} + B(B&&, int = (throw 42, 0)) noexcept; + ~B() noexcept(false); +}; +int n = 7; +struct D : public A, public B { + int * p = new int[n]; + // \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length} + // \tcode{D::D(const D\&)} non-throwing + // \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw + // \tcode{D::\~D()} potentially-throwing +}; +\end{codeblock} +Furthermore, if +\tcode{A::\~{}A()} +were virtual, +the program would be ill-formed since a function that overrides a virtual +function from a base class +shall not have a potentially-throwing exception specification +if the base class function has a non-throwing exception specification. +\end{example} + +\pnum +An exception specification is considered to be \defnx{needed}{needed!exception specification} when: +\begin{itemize} +\item in an expression, the function is selected by +overload resolution\iref{over.match,over.over}; + +\item the function is odr-used\iref{term.odr.use} or, if it appears in an +unevaluated operand, would be odr-used if the expression were +potentially-evaluated; + +\item the exception specification is compared to that of another +declaration (e.g., an explicit specialization or an overriding virtual +function); + +\item the function is defined; or + +\item the exception specification is needed for a defaulted +function that calls the function. +\begin{note} +A defaulted declaration does not require the +exception specification of a base member function to be evaluated +until the implicit exception specification of the derived +function is needed, but an explicit \grammarterm{noexcept-specifier} needs +the implicit exception specification to compare against. +\end{note} +\end{itemize} +The exception specification of a defaulted +function is evaluated as described above only when needed; similarly, the +\grammarterm{noexcept-specifier} of a specialization of a function +template or member function of a class template is instantiated only when +needed. +% +\indextext{exception specification|)} +\indextext{exception handling|)} + \rSec1[dcl.init]{Initializers}% \rSec2[dcl.init.general]{General}% @@ -8827,7 +9094,7 @@ effect. The order in which the \grammarterm{attribute-token}{s} appear in an \grammarterm{attribute-list} is not significant. If a keyword\iref{lex.key} -or an alternative token\iref{lex.digraph} that satisfies the syntactic requirements +or an alternative token\iref{lex.operators} that satisfies the syntactic requirements of an \grammarterm{identifier}\iref{lex.name} is contained in an \grammarterm{attribute-token}, it is considered an identifier. No name @@ -8838,7 +9105,7 @@ \pnum Each \grammarterm{attribute-specifier-seq} is said to \defn{appertain} to some entity or statement, identified by the syntactic context -where it appears\iref{stmt.stmt,dcl.dcl,dcl.decl}. +where it appears\iref{stmt,dcl,dcl.decl}. If an \grammarterm{attribute-specifier-seq} that appertains to some entity or statement contains an \grammarterm{attribute} or \grammarterm{alignment-specifier} that is not allowed to apply to that diff --git a/source/exceptions.tex b/source/exceptions.tex deleted file mode 100644 index 67e052c476..0000000000 --- a/source/exceptions.tex +++ /dev/null @@ -1,1152 +0,0 @@ -%!TEX root = std.tex -\rSec0[except]{Exception handling}% -\indextext{exception handling|(} - -\gramSec[gram.except]{Exception handling} - -\indextext{exception object|see{exception handling, exception object}}% -\indextext{object!exception|see{exception handling, exception object}} - -\rSec1[except.pre]{Preamble} - -\pnum -Exception handling provides a way of transferring control and information -from a point in the execution of a thread to an exception handler -associated with a point previously passed by the execution. -A handler will be invoked only by throwing an exception -in code executed in the handler's try block -or in functions called from the handler's try block. - -\indextext{\idxcode{try}}% -% -\begin{bnf} -\nontermdef{try-block}\br - \keyword{try} compound-statement handler-seq -\end{bnf} - -\indextext{\idxcode{try}}% -% -\begin{bnf} -\nontermdef{function-try-block}\br - \keyword{try} \opt{ctor-initializer} compound-statement handler-seq -\end{bnf} - -\begin{bnf} -\nontermdef{handler-seq}\br - handler \opt{handler-seq} -\end{bnf} - -\indextext{\idxcode{catch}}% -% -\begin{bnf} -\nontermdef{handler}\br - \keyword{catch} \terminal{(} exception-declaration \terminal{)} compound-statement -\end{bnf} - -\begin{bnf} -\nontermdef{exception-declaration}\br - \opt{attribute-specifier-seq} type-specifier-seq declarator\br - \opt{attribute-specifier-seq} type-specifier-seq \opt{abstract-declarator}\br - \terminal{...} -\end{bnf} - -The optional \grammarterm{attribute-specifier-seq} in an \grammarterm{exception-declaration} -appertains to the parameter of the catch clause\iref{except.handle}. - -\pnum -\indextext{exception handling!try block}% -\indextext{exception handling!handler}% -\indextext{try block|see{exception handling, try block}}% -\indextext{handler|see{exception handling, handler}}% -A \grammarterm{try-block} is a \grammarterm{statement}\iref{stmt.pre}. -\begin{note} -Within this Clause -``try block'' is taken to mean both \grammarterm{try-block} and -\grammarterm{function-try-block}. -\end{note} - -\pnum -\indextext{exception handling!\idxcode{goto}}% -\indextext{exception handling!\idxcode{switch}}% -\indextext{\idxcode{goto}!and try block}% -\indextext{\idxcode{switch}!and try block}% -\indextext{\idxcode{goto}!and handler}% -\indextext{\idxcode{switch}!and handler}% -The \grammarterm{compound-statement} of a try block or of a handler is a -control-flow-limited statement\iref{stmt.label}. -\begin{example} -\begin{codeblock} -void f() { - goto l1; // error - goto l2; // error - try { - goto l1; // OK - goto l2; // error - l1: ; - } catch (...) { - l2: ; - goto l1; // error - goto l2; // OK - } -} - -\end{codeblock} -\end{example} -\indextext{\idxcode{goto}!and try block}% -\indextext{\idxcode{switch}!and try block}% -\indextext{\idxcode{return}!and try block}% -\indextext{\idxcode{continue}!and try block}% -\indextext{\idxcode{goto}!and handler}% -\indextext{\idxcode{switch}!and handler}% -\indextext{\idxcode{return}!and handler}% -\indextext{\idxcode{continue}!and handler}% -A -\keyword{goto}, -\keyword{break}, -\keyword{return}, -or -\keyword{continue} -statement can be used to transfer control out of -a try block or handler. -When this happens, each variable declared in the try block -will be destroyed in the context that -directly contains its declaration. -\begin{example} -\begin{codeblock} -lab: try { - T1 t1; - try { - T2 t2; - if (@\grammarterm{condition}@) - goto lab; - } catch(...) { @\tcode{/* handler 2 */}@ } - } catch(...) { @\tcode{/* handler 1 */}@ } -\end{codeblock} - -Here, executing -\tcode{goto lab;} -will destroy first -\tcode{t2}, -then -\tcode{t1}, -assuming the -\grammarterm{condition} -does not declare a variable. -Any exception thrown while destroying -\tcode{t2} -will result in executing -\tcode{handler 2}; -any exception thrown while destroying -\tcode{t1} -will result in executing -\tcode{handler 1}. -\end{example} - -\pnum -\indextext{function try block|see{exception handling, function try block}}% -\indextext{exception handling!function try block}% -A -\grammarterm{function-try-block} -associates a -\grammarterm{handler-seq} -with the -\grammarterm{ctor-initializer}, -if present, and the -\grammarterm{compound-statement}. -An exception -thrown during the execution of the -\grammarterm{compound-statement} -or, for constructors and destructors, during the initialization or -destruction, respectively, of the class's subobjects, -transfers control to a handler in a -\grammarterm{function-try-block} -in the same way as an exception thrown during the execution of a -\grammarterm{try-block} -transfers control to other handlers. -\begin{example} -\begin{codeblock} -int f(int); -class C { - int i; - double d; -public: - C(int, double); -}; - -C::C(int ii, double id) -try : i(f(ii)), d(id) { - // constructor statements -} catch (...) { - // handles exceptions thrown from the ctor-initializer and from the constructor statements -} -\end{codeblock} -\end{example} - -\pnum -In this Clause, ``before'' and ``after'' refer to the -``sequenced before'' relation\iref{intro.execution}. - -\rSec1[except.throw]{Throwing an exception}% -\indextext{exception handling!throwing}% -\indextext{throwing|see{exception handling, throwing}} - -\pnum -Throwing an exception transfers control to a handler. -\begin{note} -An exception can be thrown from one of the following contexts: -\grammarterm{throw-expression}{s}\iref{expr.throw}, -allocation functions\iref{basic.stc.dynamic.allocation}, -\keyword{dynamic_cast}\iref{expr.dynamic.cast}, -\keyword{typeid}\iref{expr.typeid}, -\grammarterm{new-expression}{s}\iref{expr.new}, and standard library -functions\iref{structure.specifications}. -\end{note} -An object is passed and the type of that object determines which handlers -can catch it. -\begin{example} -\begin{codeblock} -throw "Help!"; -\end{codeblock} -can be caught by a -\grammarterm{handler} -of -\keyword{const} -\tcode{\keyword{char}*} -type: -\begin{codeblock} -try { - // ... -} catch(const char* p) { - // handle character string exceptions here -} -\end{codeblock} -and -\begin{codeblock} -class Overflow { -public: - Overflow(char,double,double); -}; - -void f(double x) { - throw Overflow('+',x,3.45e107); -} -\end{codeblock} -can be caught by a handler for exceptions of type -\tcode{Overflow}: -\begin{codeblock} -try { - f(1.2); -} catch(Overflow& oo) { - // handle exceptions of type \tcode{Overflow} here -} -\end{codeblock} -\end{example} - -\pnum -\indextext{exception handling!throwing}% -\indextext{exception handling!handler}% -\indextext{exception handling!nearest handler}% -When an exception is thrown, control is transferred to the nearest handler with -a matching type\iref{except.handle}; ``nearest'' means the handler -for which the -\grammarterm{compound-statement} or -\grammarterm{ctor-initializer} -following the -\keyword{try} -keyword was most recently entered by the thread of control and not yet exited. - -\pnum -Throwing an exception -initializes an object with dynamic storage duration, -called the -\defnx{exception object}{exception handling!exception object}. -If the type of the exception object would be -an incomplete type\iref{basic.types.general}, -an abstract class type\iref{class.abstract}, -or a pointer to an incomplete type other than -\cv{}~\keyword{void}\iref{basic.compound}, -the program is ill-formed. - -\pnum -\indextext{exception handling!memory}% -\indextext{exception handling!rethrowing}% -\indextext{exception handling!exception object}% -The memory for the exception object is -allocated in an unspecified way, except as noted in~\ref{basic.stc.dynamic.allocation}. -If a handler exits by rethrowing, control is passed to another handler for -the same exception object. -The points of potential destruction for the exception object are: -\begin{itemize} -\item -when an active handler for the exception exits by -any means other than -rethrowing, -immediately after the destruction of the object (if any) -declared in the \grammarterm{exception-declaration} in the handler; - -\item -when an object of type \tcode{std::exception_ptr}\iref{propagation} -that refers to the exception object is destroyed, -before the destructor of \tcode{std::exception_ptr} returns. -\end{itemize} - -Among all points of potential destruction for the exception object, -there is an unspecified last one -where the exception object is destroyed. -All other points happen before that last one\iref{intro.races}. -\begin{note} -No other thread synchronization is implied in exception handling. -\end{note} -The implementation may then -deallocate the memory for the exception object; any such deallocation -is done in an unspecified way. -\begin{note} -A thrown exception does not -propagate to other threads unless caught, stored, and rethrown using -appropriate library functions; see~\ref{propagation} and~\ref{futures}. -\end{note} - -\pnum -\indextext{exception handling!exception object!constructor}% -\indextext{exception handling!exception object!destructor}% -Let \tcode{T} denote the type of the exception object. -Copy-initialization of an object of type \tcode{T} from -an lvalue of type \tcode{const T} in a context unrelated to \tcode{T} -shall be well-formed. -If \tcode{T} is a class type, -the selected constructor is odr-used\iref{basic.def.odr} and -the destructor of \tcode{T} is potentially invoked\iref{class.dtor}. - -\pnum -\indextext{exception handling!rethrow}% -\indextext{rethrow|see{exception handling, rethrow}}% -An exception is considered caught when a handler for that exception -becomes active\iref{except.handle}. -\begin{note} -An exception can have active handlers and still be considered uncaught if -it is rethrown. -\end{note} - -\pnum -\indextext{exception handling!terminate called@\tcode{terminate} called}% -\indextext{\idxcode{terminate}!called}% -If the exception handling mechanism -handling an uncaught exception\iref{except.uncaught} -directly invokes a function that exits via an -exception, the function \tcode{std::terminate} is invoked\iref{except.terminate}. -\begin{example} -\begin{codeblock} -struct C { - C() { } - C(const C&) { - if (std::uncaught_exceptions()) { - throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object\iref{except.handle} - } - } -}; - -int main() { - try { - throw C(); // calls \tcode{std::terminate} if construction of the handler's - // \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision} - } catch(C) { } -} -\end{codeblock} -\end{example} -\begin{note} -If a destructor directly invoked by stack unwinding exits via an exception, -\tcode{std::terminate} is invoked. -\end{note} - - -\rSec1[except.ctor]{Constructors and destructors}% -\indextext{exception handling!constructors and destructors}% -\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}% -\indextext{destructor!exception handling|see{exception handling, constructors and destructors}} - -\pnum -\indextext{unwinding!stack}% -As control passes from the point where an exception is thrown -to a handler, -objects are destroyed by a process, -specified in this subclause, called \defn{stack unwinding}. - -\pnum -Each object with automatic storage duration is destroyed if it has been -constructed, but not yet destroyed, -since the try block was entered. -If an exception is thrown during the destruction of temporaries or -local variables for a \keyword{return} statement\iref{stmt.return}, -the destructor for the returned object (if any) is also invoked. -The objects are destroyed in the reverse order of the completion -of their construction. -\begin{example} -\begin{codeblock} -struct A { }; - -struct Y { ~Y() noexcept(false) { throw 0; } }; - -A f() { - try { - A a; - Y y; - A b; - return {}; // \#1 - } catch (...) { - } - return {}; // \#2 -} -\end{codeblock} -At \#1, the returned object of type \tcode{A} is constructed. -Then, the local variable \tcode{b} is destroyed\iref{stmt.jump}. -Next, the local variable \tcode{y} is destroyed, -causing stack unwinding, -resulting in the destruction of the returned object, -followed by the destruction of the local variable \tcode{a}. -Finally, the returned object is constructed again at \#2. -\end{example} - -\pnum -If the initialization of an object -other than by delegating constructor -is terminated by an exception, -the destructor is invoked for -each of the object's subobjects -that were known to be initialized by the object's initialization and -whose initialization has completed\iref{dcl.init}. -\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} -\indextext{subobject!initialized, known to be}% -A subobject is \defn{known to be initialized} -if it is not an anonymous union member and -its initialization is specified -\begin{itemize} -\item in \ref{class.base.init} for initialization by constructor, -\item in \ref{class.copy.ctor} for initialization by defaulted copy/move constructor, -\item in \ref{class.inhctor.init} for initialization by inherited constructor, -\item in \ref{dcl.init.aggr} for aggregate initialization, -\item in \ref{expr.prim.lambda.capture} for the initialization of -the closure object when evaluating a \grammarterm{lambda-expression}, -\item in \ref{dcl.init.general} for -default-initialization, value-initialization, or direct-initialization -of an array. -\end{itemize} -\begin{note} -This includes virtual base class subobjects -if the initialization -is for a complete object, and -can include variant members -that were nominated explicitly by -a \grammarterm{mem-initializer} or \grammarterm{designated-initializer-clause} or -that have a default member initializer. -\end{note} -If the destructor of an object is terminated by an exception, -each destructor invocation -that would be performed after executing the body of the destructor\iref{class.dtor} and -that has not yet begun execution -is performed. -\begin{note} -This includes virtual base class subobjects if -the destructor was invoked for a complete object. -\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, -if any. - -\pnum -If the \grammarterm{compound-statement} -of the \grammarterm{function-body} -of a delegating constructor -for an object exits via -an exception, the object's destructor is invoked. -Such destruction is sequenced before entering a handler of the -\grammarterm{function-try-block} of a delegating constructor for that object, if any. - -\pnum -\begin{note} -If the object was allocated by a \grammarterm{new-expression}\iref{expr.new}, -the matching deallocation function\iref{basic.stc.dynamic.deallocation}, -if any, is called to free the storage occupied by the object. -\end{note} - - -\rSec1[except.handle]{Handling an exception} -\indextext{exception handling!handler|(}% - -\pnum -The -\grammarterm{exception-declaration} -in a -\grammarterm{handler} -describes the type(s) of exceptions that can cause -that -\grammarterm{handler} -to be entered. -\indextext{exception handling!handler!incomplete type in}% -\indextext{exception handling!handler!rvalue reference in}% -\indextext{exception handling!handler!array in}% -\indextext{exception handling!handler!pointer to function in}% -The -\grammarterm{exception-declaration} -shall not denote an incomplete type, an abstract class type, or an rvalue reference type. -The -\grammarterm{exception-declaration} -shall not denote a pointer or reference to an -incomplete type, other than ``pointer to \cv{}~\keyword{void}''. - -\pnum -A handler of type -\indextext{array!handler of type}% -``array of \tcode{T}'' or -\indextext{function!handler of type}% -function type \tcode{T} -is adjusted to be of type -``pointer to \tcode{T}''. - -\pnum -\indextext{exception handling!handler!match|(}% -A -\grammarterm{handler} -is a match for -an exception object -of type -\tcode{E} -if -\begin{itemize} -\item% -The \grammarterm{handler} is of type \cv{}~\tcode{T} or -\cv{}~\tcode{T\&} and -\tcode{E} and \tcode{T} -are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or -\item% -the \grammarterm{handler} is of type \cv{}~\tcode{T} or -\cv{}~\tcode{T\&} and -\tcode{T} is an unambiguous public base class of \tcode{E}, or -\item% -the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} -where \tcode{T} is a pointer or pointer-to-member type and -\tcode{E} is a pointer or pointer-to-member type -that can be converted to \tcode{T} by one or more of -\begin{itemize} - -\item% -a standard pointer conversion\iref{conv.ptr} not involving conversions -to pointers to private or protected or ambiguous classes -\item% -a function pointer conversion\iref{conv.fctptr} -\item% -a qualification conversion\iref{conv.qual}, or - -\end{itemize} - -\item -the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}. - -\end{itemize} - -\begin{note} -A -\grammarterm{throw-expression} -whose operand is an integer literal with value zero does not match a handler of -pointer or pointer-to-member type. -A handler of reference to array or function type -is never a match for any exception object\iref{expr.throw}. -\end{note} - -\begin{example} -\begin{codeblock} -class Matherr { @\commentellip@ virtual void vf(); }; -class Overflow: public Matherr { @\commentellip@ }; -class Underflow: public Matherr { @\commentellip@ }; -class Zerodivide: public Matherr { @\commentellip@ }; - -void f() { - try { - g(); - } catch (Overflow oo) { - // ... - } catch (Matherr mm) { - // ... - } -} -\end{codeblock} -Here, the -\tcode{Overflow} -handler will catch exceptions of type -\tcode{Overflow} -and the -\tcode{Matherr} -handler will catch exceptions of type -\tcode{Matherr} -and of all types publicly derived from -\tcode{Matherr} -including exceptions of type -\tcode{Underflow} -and -\tcode{Zerodivide}. -\end{example} - -\pnum -The handlers for a try block are tried in order of appearance. -\begin{note} -This makes it possible to write handlers that can never be -executed, for example by placing a handler for a final derived class after -a handler for a corresponding unambiguous public base class. -\end{note} - -\pnum -A -\tcode{...} -in a handler's -\grammarterm{exception-declaration} -functions similarly to -\tcode{...} -in a function parameter declaration; -it specifies a match for any exception. -If present, a -\tcode{...} -handler shall be the last handler for its try block. - -\pnum -If no match is found among the handlers for a try block, -the search for a matching -handler continues in a dynamically surrounding try block -of the same thread. - -\pnum -A handler is considered \defnx{active}{exception handling!handler!active} when -initialization is complete for the parameter (if any) of the catch clause. -\begin{note} -The stack will have been unwound at that point. -\end{note} -Also, an implicit handler is considered active when -the function \tcode{std::terminate} -is entered due to a throw. A handler is no longer considered active when the -catch clause exits. - -\pnum -\indextext{currently handled exception|see{exception handling, currently handled exception}}% -The exception with the most recently activated handler that is -still active is called the -\defnx{currently handled exception}{exception handling!currently handled exception}. - -\pnum -If no matching handler is found, -the function \tcode{std::terminate} is invoked; -whether or not the stack is unwound before this invocation of -\tcode{std::terminate} -is \impldef{stack unwinding before invocation of -\tcode{std::terminate}}\iref{except.terminate}. - -\pnum -Referring to any non-static member or base class of an object -in the handler for a -\grammarterm{function-try-block} -of a constructor or destructor for that object results in undefined behavior. - -\pnum -Exceptions thrown in destructors of objects with static storage duration or in -constructors of objects associated with non-block variables with static storage duration are not caught by a -\grammarterm{function-try-block} -on -the \tcode{main} function\iref{basic.start.main}. -Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a -\grammarterm{function-try-block} -on the initial function of the thread. - -\pnum -If a \keyword{return} statement\iref{stmt.return} appears in a handler of the -\grammarterm{function-try-block} -of a -constructor, the program is ill-formed. - -\pnum -The currently handled exception -is rethrown if control reaches the end of a handler of the -\grammarterm{function-try-block} -of a constructor or destructor. -Otherwise, flowing off the end of -the \grammarterm{compound-statement} -of a \grammarterm{handler} -of a \grammarterm{function-try-block} -is equivalent to flowing off the end of -the \grammarterm{compound-statement} -of that function (see \ref{stmt.return}). - -\pnum -The variable declared by the \grammarterm{exception-declaration}, of type -\cv{}~\tcode{T} or \cv{}~\tcode{T\&}, is initialized from the exception object, -of type \tcode{E}, as follows: -\begin{itemize} -\item -if \tcode{T} is a base class of \tcode{E}, -the variable is copy-initialized\iref{dcl.init} -from an lvalue of type \tcode{T} designating the corresponding base class subobject -of the exception object; -\item otherwise, the variable is copy-initialized\iref{dcl.init} -from an lvalue of type \tcode{E} designating the exception object. -\end{itemize} - -The lifetime of the variable ends -when the handler exits, after the -destruction of any objects with automatic storage duration initialized -within the handler. - -\pnum -When the handler declares an object, -any changes to that object will not affect the exception object. -When the handler declares a reference to an object, -any changes to the referenced object are changes to the -exception object and will have effect should that object be rethrown.% -\indextext{exception handling!handler!match|)}% -\indextext{exception handling!handler|)} - -\rSec1[except.spec]{Exception specifications}% -\indextext{exception specification|(} - -\pnum -The predicate indicating whether a function cannot exit via an exception -is called the \defn{exception specification} of the function. -If the predicate is false, -the function has a -\indextext{exception specification!potentially-throwing}% -\defnx{potentially-throwing exception specification}% -{potentially-throwing!exception specification}, -otherwise it has a -\indextext{exception specification!non-throwing}% -\defn{non-throwing exception specification}. -The exception specification is either defined implicitly, -or defined explicitly -by using a \grammarterm{noexcept-specifier} -as a suffix of a function declarator\iref{dcl.fct}. - -\begin{bnf} -\nontermdef{noexcept-specifier}\br - \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br - \keyword{noexcept}\br -\end{bnf} - -\pnum -\indextext{exception specification!noexcept!constant expression and}% -In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression}, -if supplied, shall be a contextually converted constant expression -of type \keyword{bool}\iref{expr.const}; -that constant expression is the exception specification of -the function type in which the \grammarterm{noexcept-specifier} appears. -A \tcode{(} token that follows \keyword{noexcept} is part of the -\grammarterm{noexcept-specifier} and does not commence an -initializer\iref{dcl.init}. -The \grammarterm{noexcept-specifier} \keyword{noexcept} -without a \grammarterm{constant-expression} -is -equivalent to the \grammarterm{noexcept-specifier} -\tcode{\keyword{noexcept}(\keyword{true})}. -\begin{example} -\begin{codeblock} -void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool} -void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing -\end{codeblock} -\end{example} - -\pnum -If a declaration of a function -does not have a \grammarterm{noexcept-specifier}, -the declaration has a potentially throwing exception specification -unless it is a destructor or a deallocation function -or is defaulted on its first declaration, -in which cases the exception specification -is as specified below -and no other declaration for that function -shall have a \grammarterm{noexcept-specifier}. -In an explicit instantiation\iref{temp.explicit} -a \grammarterm{noexcept-specifier} may be specified, -but is not required. -If a \grammarterm{noexcept-specifier} is specified -in an explicit instantiation, -the exception specification shall be the same as -the exception specification of all other declarations of that function. -A diagnostic is required only if the -exception specifications are not the same -within a single translation unit. - -\pnum -\indextext{exception specification!virtual function and}% -If a virtual function has a -non-throwing exception specification, -all declarations, including the definition, of any function -that overrides that virtual function in any derived class -shall have a non-throwing -exception specification, -unless the overriding function is defined as deleted. -\begin{example} -\begin{codeblock} -struct B { - virtual void f() noexcept; - virtual void g(); - virtual void h() noexcept = delete; -}; - -struct D: B { - void f(); // error - void g() noexcept; // OK - void h() = delete; // OK -}; -\end{codeblock} - -The declaration of -\tcode{D::f} -is ill-formed because it -has a potentially-throwing exception specification, -whereas -\tcode{B::f} -has a non-throwing exception specification. -\end{example} - -\pnum -\indextext{exception handling!terminate called@\tcode{terminate} called}% -\indextext{\idxcode{terminate}!called}% -Whenever an exception is thrown -and the search for a handler\iref{except.handle} -encounters the outermost block of a function with a -non-throwing exception specification, -the function \tcode{std::terminate} is invoked\iref{except.terminate}. -\begin{note} -An implementation is not permitted to reject an expression merely because, when -executed, it throws or might -throw an exception from a function with a non-throwing exception specification. -\end{note} -\begin{example} -\begin{codeblock} -extern void f(); // potentially-throwing - -void g() noexcept { - f(); // valid, even if \tcode{f} throws - throw 42; // valid, effectively a call to \tcode{std::terminate} -} -\end{codeblock} -The call to -\tcode{f} -is well-formed despite the possibility for it to throw an exception. -\end{example} - -\pnum -An expression $E$ is -\defnx{potentially-throwing}{potentially-throwing!expression} if -\begin{itemize} -\item -$E$ is a function call\iref{expr.call} -whose \grammarterm{postfix-expression} -has a function type, -or a pointer-to-function type, -with a potentially-throwing exception specification, -or -\item -$E$ implicitly invokes a function -(such as an overloaded operator, -an allocation function in a \grammarterm{new-expression}, -a constructor for a function argument, -or a destructor if $E$ is a full-expression\iref{intro.execution}) -that has a potentially-throwing exception specification, -or -\item -$E$ is a \grammarterm{throw-expression}\iref{expr.throw}, -or -\item -$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and -requires a runtime check\iref{expr.dynamic.cast}, -or -\item -$E$ is a \keyword{typeid} expression applied to a -(possibly parenthesized) built-in unary \tcode{*} operator -applied to a pointer to a -polymorphic class type\iref{expr.typeid}, -or -\item -any of the immediate subexpressions\iref{intro.execution} -of $E$ is potentially-throwing. -\end{itemize} - -\pnum -An implicitly-declared constructor for a class \tcode{X}, -or a constructor without a \grammarterm{noexcept-specifier} -that is defaulted on its first declaration, -has a potentially-throwing exception specification -if and only if -any of the following constructs is potentially-throwing: -\begin{itemize} -\item -the invocation of a constructor selected by overload resolution -in the implicit definition of the constructor -for class \tcode{X} -to initialize a potentially constructed subobject, or -\item -a subexpression of such an initialization, -such as a default argument expression, or, -\item -for a default constructor, a default member initializer. -\end{itemize} -\begin{note} -Even though destructors for fully-constructed subobjects -are invoked when an exception is thrown -during the execution of a constructor\iref{except.ctor}, -their exception specifications do not contribute -to the exception specification of the constructor, -because an exception thrown from such a destructor -would call the function \tcode{std::terminate} -rather than escape the constructor\iref{except.throw,except.terminate}. -\end{note} - -\pnum -The exception specification for an implicitly-declared destructor, -or a destructor without a \grammarterm{noexcept-specifier}, -is potentially-throwing if and only if -any of the destructors -for any of its potentially constructed subobjects -has a potentially-throwing exception specification or -the destructor is virtual and the destructor of any virtual base class -has a potentially-throwing exception specification. - -\pnum -The exception specification for an implicitly-declared assignment operator, -or an assignment-operator without a \grammarterm{noexcept-specifier} -that is defaulted on its first declaration, -is potentially-throwing if and only if -the invocation of any assignment operator -in the implicit definition is potentially-throwing. - -\pnum -A deallocation function\iref{basic.stc.dynamic.deallocation} -with no explicit \grammarterm{noexcept-specifier} -has a non-throwing exception specification. - -\pnum -The exception specification for a comparison operator function\iref{over.binary} -without a \grammarterm{noexcept-specifier} -that is defaulted on its first declaration -is potentially-throwing if and only if -any expression -in the implicit definition is potentially-throwing. - -\pnum -\begin{example} -\begin{codeblock} -struct A { - A(int = (A(5), 0)) noexcept; - A(const A&) noexcept; - A(A&&) noexcept; - ~A(); -}; -struct B { - B() noexcept; - B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})} - B(B&&, int = (throw 42, 0)) noexcept; - ~B() noexcept(false); -}; -int n = 7; -struct D : public A, public B { - int * p = new int[n]; - // \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length} - // \tcode{D::D(const D\&)} non-throwing - // \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw - // \tcode{D::\~D()} potentially-throwing -}; -\end{codeblock} -Furthermore, if -\tcode{A::\~{}A()} -were virtual, -the program would be ill-formed since a function that overrides a virtual -function from a base class -shall not have a potentially-throwing exception specification -if the base class function has a non-throwing exception specification. -\end{example} - -\pnum -An exception specification is considered to be \defnx{needed}{needed!exception specification} when: -\begin{itemize} -\item in an expression, the function is selected by -overload resolution\iref{over.match,over.over}; - -\item the function is odr-used\iref{term.odr.use} or, if it appears in an -unevaluated operand, would be odr-used if the expression were -potentially-evaluated; - -\item the exception specification is compared to that of another -declaration (e.g., an explicit specialization or an overriding virtual -function); - -\item the function is defined; or - -\item the exception specification is needed for a defaulted -function that calls the function. -\begin{note} -A defaulted declaration does not require the -exception specification of a base member function to be evaluated -until the implicit exception specification of the derived -function is needed, but an explicit \grammarterm{noexcept-specifier} needs -the implicit exception specification to compare against. -\end{note} -\end{itemize} -The exception specification of a defaulted -function is evaluated as described above only when needed; similarly, the -\grammarterm{noexcept-specifier} of a specialization of a function -template or member function of a class template is instantiated only when -needed. -% -\indextext{exception specification|)} - -\rSec1[except.special]{Special functions} - -\rSec2[except.special.general]{General} - -\pnum -The function \tcode{std::terminate}\iref{except.terminate} -is used by the exception -handling mechanism for coping with errors related to the exception handling -mechanism itself. The function -\tcode{std::current_exception()}\iref{propagation} and the class -\tcode{std::nested_exception}\iref{except.nested} can be used by a program to -capture the currently handled exception. - -\rSec2[except.terminate]{The \tcode{std::terminate} function} - -\pnum -\indextext{\idxcode{terminate}}% -% FIXME: What does it mean to abandon exception handling? -In some situations, exception handling is abandoned -for less subtle error handling techniques. -\begin{note} -These situations are: -\indextext{\idxcode{terminate}!called}% -\begin{itemize} -\item% -when the exception handling mechanism, after completing -the initialization of the exception object -but before -activation of a handler for the exception\iref{except.throw}, -calls a function that exits -via an exception, or - -\item% -when the exception handling mechanism cannot find a handler for a thrown exception\iref{except.handle}, or - -\item when the search for a handler\iref{except.handle} encounters the -outermost block of a function -with a non-throwing exception specification\iref{except.spec}, or - -\item% -when the destruction of an object during stack unwinding\iref{except.ctor} -terminates by throwing an exception, or - -\item% -when initialization of a non-block -variable with static or thread storage duration\iref{basic.start.dynamic} -exits via an exception, or - -\item% -when destruction of an object with static or thread storage duration exits -via an exception\iref{basic.start.term}, or - -\item% -when execution of a function registered with -\tcode{std::atexit} or \tcode{std::at_quick_exit} -exits via an exception\iref{support.start.term}, or - -\item% -when a -\grammarterm{throw-expression}\iref{expr.throw} -with no operand attempts to rethrow an exception and no exception is being -handled\iref{except.throw}, or - -\item% -when the function \tcode{std::nested_exception::rethrow_nested} is called for an object -that has captured no exception\iref{except.nested}, or - -\item% -when execution of the initial function of a thread exits via -an exception\iref{thread.thread.constr}, or - -\item% -for a parallel algorithm whose \tcode{ExecutionPolicy} specifies such -behavior\iref{execpol.seq,execpol.par,execpol.parunseq}, -when execution of an element access function\iref{algorithms.parallel.defns} -of the parallel algorithm exits via an exception\iref{algorithms.parallel.exceptions}, or - -\item% -when the destructor or the move assignment operator is invoked on an object -of type \tcode{std::thread} that refers to -a joinable thread\iref{thread.thread.destr,thread.thread.assign}, or - -\item% -when a call to a \tcode{wait()}, \tcode{wait_until()}, or \tcode{wait_for()} -function on a condition variable\iref{thread.condition.condvar,thread.condition.condvarany} -fails to meet a postcondition, or - -\item% -when a callback invocation exits via an exception -when requesting stop on -a \tcode{std::stop_source} or -a \tcode{std::in\-place_stop_source}\iref{stopsource.mem,stopsource.inplace.mem}, -or in the constructor of -\tcode{std::stop_callback} or -\tcode{std::inplace_stop_callback}\iref{stopcallback.cons,stopcallback.inplace.cons} -when a callback invocation exits via an exception, or - -\item% -when a \tcode{run_loop} object is destroyed -that is still in the \tcode{running} state\iref{exec.run.loop}, or - -\item% -when \tcode{unhandled_stopped} is called on -a \tcode{with_awaitable_senders} object\iref{exec.with.awaitable.senders} -whose continuation is not a handle to a coroutine -whose promise type has an \tcode{unhandled_stopped} member function. - -\end{itemize} - -\end{note} - -\pnum -\indextext{\idxcode{terminate}}% -In such cases, -the function \tcode{std::terminate} is invoked\iref{exception.terminate}. -In the situation where no matching handler is found, it is -\impldef{stack unwinding before invocation of \tcode{std::terminate}} -whether or not the stack is unwound -before \tcode{std::terminate} is invoked. -In the situation where the search for a handler\iref{except.handle} encounters the -outermost block of a function -with a non-throwing exception specification\iref{except.spec}, it is -\impldef{whether stack is unwound before invoking the function \tcode{std::terminate} -when a \tcode{noexcept} specification is violated} -whether the stack is unwound, unwound partially, or not unwound at all -before the function \tcode{std::terminate} is invoked. -In all other situations, the stack shall not be unwound before -the function \tcode{std::terminate} -is invoked. -An implementation is not permitted to finish stack unwinding -prematurely based on a determination that the unwind process -will eventually cause an invocation of the function -\tcode{std::terminate}. - -\rSec2[except.uncaught]{The \tcode{std::uncaught_exceptions} function}% -\indexlibraryglobal{uncaught_exceptions} - -\pnum -An exception is considered uncaught -after completing the initialization of the exception object\iref{except.throw} -until completing the activation of a handler for the exception\iref{except.handle}. -\begin{note} -As a consequence, an exception is considered uncaught -during any stack unwinding resulting from it being thrown. -\end{note} -If an exception is rethrown\iref{expr.throw,propagation}, -it is considered uncaught from the point of rethrow -until the rethrown exception is caught. -The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} -returns the number of uncaught exceptions in the current thread.% -\indextext{exception handling|)} diff --git a/source/expressions.tex b/source/expressions.tex index 389ac435b8..227c9d9fbd 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1478,7 +1478,7 @@ \indextext{identifier}% An \grammarterm{identifier} is only an \grammarterm{id-expression} if it has -been suitably declared\iref{dcl.dcl} +been suitably declared\iref{dcl} or if it appears as part of a \grammarterm{declarator-id}\iref{dcl.decl}. An \grammarterm{identifier} that names a coroutine parameter refers to the copy of the parameter\iref{dcl.fct.def.coroutine}. @@ -1514,7 +1514,7 @@ the \grammarterm{unqualified-id}\iref{basic.lookup.unqual}. If the \grammarterm{unqualified-id} appears in a \grammarterm{lambda-expression} at program point $P$ and -the entity is a local entity\iref{basic.pre} or a variable declared by +the entity is a local entity\iref{basic.def.odr} or a variable declared by an \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, then let $S$ be the \grammarterm{compound-statement} of the innermost enclosing \grammarterm{lambda-expression} of $P$. @@ -2391,7 +2391,7 @@ \pnum The \grammarterm{identifier} in a \grammarterm{simple-capture} -shall denote a local entity\iref{basic.lookup.unqual,basic.pre}. +shall denote a local entity\iref{basic.lookup.unqual,basic.def.odr}. The \grammarterm{simple-capture}{s} \keyword{this} and \tcode{* \keyword{this}} denote the local entity \tcode{*\keyword{this}}. An entity that is designated by a @@ -7543,7 +7543,7 @@ \item an operation that would have undefined or erroneous behavior -as specified in \ref{intro} through \ref{cpp}, +as specified in \ref{intro} through \ref{\lastcorechapter}, excluding \ref{dcl.attr.assume} and \ref{dcl.attr.noreturn}; \begin{footnote} This includes, @@ -7714,7 +7714,7 @@ \item a \keyword{goto} statement\iref{stmt.goto}. \begin{note} -A \keyword{goto} statement introduced by equivalence\iref{stmt.stmt} +A \keyword{goto} statement introduced by equivalence\iref{stmt} is not in scope. For example, a \keyword{while} statement\iref{stmt.while} can be executed during constant evaluation. diff --git a/source/future.tex b/source/future.tex index a16d108869..28f503b4e0 100644 --- a/source/future.tex +++ b/source/future.tex @@ -16,6 +16,43 @@ An implementation may declare library names and entities described in this Clause with the \tcode{deprecated} attribute\iref{dcl.attr.deprecated}. +\rSec1[depr.local]{Non-local use of TU-local entities} + +\pnum +A declaration of a non-TU-local entity that is an exposure\iref{basic.link} +is deprecated. +\begin{note} +Such a declaration in an importable module unit is ill-formed. +\end{note} +\begin{example} +\begin{codeblock} +namespace { + struct A { + void f() {} + }; +} +A h(); // deprecated: not internal linkage +inline void g() {A().f();} // deprecated: inline and not internal linkage +\end{codeblock} +\end{example} + +\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} + +\pnum +For compatibility with prior revisions of \Cpp{}, a \keyword{constexpr} +static data member may be redundantly redeclared outside the class with no +initializer\iref{basic.def,class.static.data}. +This usage is deprecated. +\begin{example} +\begin{codeblock} +struct A { + static constexpr int n = 5; // definition (declaration in \CppXIV{}) +}; + +constexpr int A::n; // redundant declaration (definition in \CppXIV{}) +\end{codeblock} +\end{example} + \rSec1[depr.capture.this]{Implicit capture of \tcode{*this} by reference} \pnum @@ -114,43 +151,14 @@ \end{codeblock} \end{example} - -\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} +\rSec1[depr.lit]{Literal operator function declarations using an identifier} \pnum -For compatibility with prior revisions of \Cpp{}, a \keyword{constexpr} -static data member may be redundantly redeclared outside the class with no -initializer\iref{basic.def,class.static.data}. -This usage is deprecated. -\begin{example} +A \grammarterm{literal-operator-id}\iref{over.literal} of the form \begin{codeblock} -struct A { - static constexpr int n = 5; // definition (declaration in \CppXIV{}) -}; - -constexpr int A::n; // redundant declaration (definition in \CppXIV{}) +operator @\grammarterm{unevaluataed-string}@ @\grammarterm{identifier}@ \end{codeblock} -\end{example} - -\rSec1[depr.local]{Non-local use of TU-local entities} - -\pnum -A declaration of a non-TU-local entity that is an exposure\iref{basic.link} is deprecated. -\begin{note} -Such a declaration in an importable module unit is ill-formed. -\end{note} -\begin{example} -\begin{codeblock} -namespace { - struct A { - void f() {} - }; -} -A h(); // deprecated: not internal linkage -inline void g() {A().f();} // deprecated: inline and not internal linkage -\end{codeblock} -\end{example} \rSec1[depr.impldec]{Implicit declaration of copy functions} @@ -166,15 +174,6 @@ It is possible that future versions of \Cpp{} will specify that these implicit definitions are deleted\iref{dcl.fct.def.delete}. -\rSec1[depr.lit]{Literal operator function declarations using an identifier} - -\pnum -A \grammarterm{literal-operator-id}\iref{over.literal} of the form -\begin{codeblock} -operator @\grammarterm{unevaluated-string}@ @\grammarterm{identifier}@ -\end{codeblock} -is deprecated. - \rSec1[depr.template.template]{\tcode{template} keyword before qualified names} \pnum @@ -244,86 +243,6 @@ #define @\xname{bool_true_false_are_defined}@ 1 \end{codeblock} -\rSec1[depr.relops]{Relational operators}% -\indexlibraryglobal{rel_ops}% - -\pnum -The header \libheaderref{utility} has the following additions: - -\begin{codeblock} -namespace std::rel_ops { - template bool operator!=(const T&, const T&); - template bool operator> (const T&, const T&); - template bool operator<=(const T&, const T&); - template bool operator>=(const T&, const T&); -} -\end{codeblock} - -\pnum -To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} -and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, -the library provides the following: - -\indexlibrary{\idxcode{operator"!=}}% -\begin{itemdecl} -template bool operator!=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{EqualityComparable} requirements (\tref{cpp17.equalitycomparable}). - -\pnum -\returns -\tcode{!(x == y)}. -\end{itemdescr} - -\indexlibraryglobal{operator>}% -\begin{itemdecl} -template bool operator>(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{y < x}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator<=}}% -\begin{itemdecl} -template bool operator<=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{!(y < x)}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator>=}}% -\begin{itemdecl} -template bool operator>=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{!(x < y)}. -\end{itemdescr} - \rSec1[depr.cerrno]{Deprecated error numbers} \pnum @@ -483,6 +402,86 @@ whose value is the strictest alignment of all types listed in \tcode{Types}. \end{itemdescr} +\rSec1[depr.relops]{Relational operators}% +\indexlibraryglobal{rel_ops}% + +\pnum +The header \libheaderref{utility} has the following additions: + +\begin{codeblock} +namespace std::rel_ops { + template bool operator!=(const T&, const T&); + template bool operator> (const T&, const T&); + template bool operator<=(const T&, const T&); + template bool operator>=(const T&, const T&); +} +\end{codeblock} + +\pnum +To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} +and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, +the library provides the following: + +\indexlibrary{\idxcode{operator"!=}}% +\begin{itemdecl} +template bool operator!=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{EqualityComparable} requirements (\tref{cpp17.equalitycomparable}). + +\pnum +\returns +\tcode{!(x == y)}. +\end{itemdescr} + +\indexlibraryglobal{operator>}% +\begin{itemdecl} +template bool operator>(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{y < x}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}}% +\begin{itemdecl} +template bool operator<=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}}% +\begin{itemdecl} +template bool operator>=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{!(x < y)}. +\end{itemdescr} + \rSec1[depr.tuple]{Tuple} \pnum @@ -600,6 +599,34 @@ \end{itemize} \end{itemdescr} +\rSec1[depr.format]{Deprecated formatting} + +\rSec2[depr.format.syn]{Header \tcode{} synopsis} + +\pnum +The header \libheaderref{format}{format.syn} has the following additions: + +\begin{codeblock} +namespace std { + template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); +} +\end{codeblock} + +\rSec2[depr.format.arg]{Formatting arguments} + +\indexlibraryglobal{visit_format_arg}% +\begin{itemdecl} +template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} +\end{itemdescr} + \rSec1[depr.iterator]{Deprecated \tcode{iterator} class template} \pnum @@ -674,34 +701,6 @@ \tcode{current}. \end{itemdescr} -\rSec1[depr.format]{Deprecated formatting} - -\rSec2[depr.format.syn]{Header \tcode{} synopsis} - -\pnum -The header \libheaderref{format}{format.syn} has the following additions: - -\begin{codeblock} -namespace std { - template - decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); -} -\end{codeblock} - -\rSec2[depr.format.arg]{Formatting arguments} - -\indexlibraryglobal{visit_format_arg}% -\begin{itemdecl} -template - decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} -\end{itemdescr} - \rSec1[depr.locale.category]{Deprecated locale category facets} \pnum diff --git a/source/intro.tex b/source/intro.tex index 4f2984457d..f56652dab5 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -256,7 +256,7 @@ Implementations are allowed, but not required, to diagnose it\iref{intro.compliance.general}. Evaluation of a constant expression\iref{expr.const} -never exhibits behavior specified as erroneous in \ref{intro} through \ref{cpp}. +never exhibits behavior specified as erroneous in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} \definition{expression-equivalent}{defns.expression.equivalent} @@ -476,7 +476,7 @@ \begin{defnote} Only one definition for such a function is in effect for the duration of the program's execution, as the result of creating the program\iref{lex.phases} and resolving the -definitions of all translation units\iref{basic.link}. +definitions of all translation units\iref{module.unit}. \end{defnote} \definition{required behavior}{defns.required.behavior} @@ -644,7 +644,7 @@ issuance of a diagnostic message). Many incorrect program constructs do not engender undefined behavior; they are required to be diagnosed. Evaluation of a constant expression\iref{expr.const} never exhibits behavior explicitly -specified as undefined in \ref{intro} through \ref{cpp}. +specified as undefined in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} \indexdefn{behavior!unspecified}% @@ -722,7 +722,7 @@ \begin{itemize} \item If a program contains no violations of the rules in -\ref{lex} through \ref{\lastlibchapter} as well as those specified in \ref{depr}, +\ref{\firstcorechapter} through \ref{\lastlibchapter} as well as those specified in \ref{depr}, a conforming implementation shall accept and correctly execute \begin{footnote} ``Correct execution'' can include undefined behavior @@ -808,7 +808,7 @@ supports all the facilities described in this document, while a freestanding implementation supports the entire \Cpp{} language -described in \ref{lex} through \ref{cpp} and +described in \ref{\firstcorechapter} through \ref{\lastcorechapter} and the subset of the library facilities described in \ref{compliance}. \pnum @@ -958,7 +958,7 @@ \pnum \indextext{standard!structure of|(}% \indextext{standard!structure of}% -\ref{lex} through \ref{cpp} describe the \Cpp{} programming +\ref{\firstcorechapter} through \ref{\lastcorechapter} describe the \Cpp{} programming language. That description includes detailed syntactic specifications in a form described in~\ref{syntax}. For convenience, \ref{gram} repeats all such syntactic specifications. diff --git a/source/lex.tex b/source/lex.tex index adb82aa862..c2c72b275d 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1,5 +1,5 @@ %!TEX root = std.tex -\rSec0[lex]{Lexical conventions} +\rSec0[lex]{Program Construction} \gramSec[gram.lex]{Lexical conventions} @@ -24,6 +24,11 @@ \rSec1[lex.separate]{Separate translation} +\pnum +\indextext{program}% +A \defn{program} consists of one or more translation units\iref{lex.phases,module.unit} +linked together. + \pnum \indextext{conventions!lexical|(}% \indextext{compilation!separate|(}% @@ -249,7 +254,8 @@ \indextext{translation!phases|)} \end{enumerate} -\rSec1[lex.charset]{Character sets} +\rSec1[lex.char]{Characters}% +\rSec2[lex.charset]{Character sets} \pnum \indextext{character set|(}% @@ -326,11 +332,69 @@ \end{floattable} \pnum -The \grammarterm{universal-character-name} construct provides a way to name -other characters. +The \defnadj{basic literal}{character set} consists of +all characters of the basic character set, +plus the control characters specified in \tref{lex.charset.literal}. + +\begin{floattable}{Additional control characters in the basic literal character set}{lex.charset.literal}{ll} +\topline +\ohdrx{2}{character} \\ \capsep +\ucode{0000} & \uname{null} \\ +\ucode{0007} & \uname{alert} \\ +\ucode{0008} & \uname{backspace} \\ +\ucode{000d} & \uname{carriage return} \\ +\end{floattable} + +\pnum +A \defn{code unit} is an integer value +of character type\iref{basic.fundamental}. +Characters in a \grammarterm{character-literal} +other than a multicharacter or non-encodable character literal or +in a \grammarterm{string-literal} are encoded as +a sequence of one or more code units, as determined +by the \grammarterm{encoding-prefix}\iref{lex.ccon,lex.string}; +this is termed the respective \defnadj{literal}{encoding}. +The \defnadj{ordinary literal}{encoding} is +the encoding applied to an ordinary character or string literal. +The \defnadj{wide literal}{encoding} is the encoding applied +to a wide character or string literal. + +\pnum +A literal encoding or a locale-specific encoding of one of +the execution character sets\iref{character.seq} +encodes each element of the basic literal character set as +a single code unit with non-negative value, +distinct from the code unit for any other such element. +\begin{note} +A character not in the basic literal character set +can be encoded with more than one code unit; +the value of such a code unit can be the same as +that of a code unit for an element of the basic literal character set. +\end{note} +\indextext{character!null}% +\indextext{wide-character!null}% +The \unicode{0000}{null} character is encoded as the value \tcode{0}. +No other element of the translation character set +is encoded with a code unit of value \tcode{0}. +The code unit value of each decimal digit character after the digit \tcode{0} (\ucode{0030}) +shall be one greater than the value of the previous. +The ordinary and wide literal encodings are otherwise +\impldef{ordinary and wide literal encodings}. +\indextext{UTF-8}% +\indextext{UTF-16}% +\indextext{UTF-32}% +For a UTF-8, UTF-16, or UTF-32 literal, +the implementation shall encode +the Unicode scalar value +corresponding to each character of the translation character set +as specified in the Unicode Standard +for the respective Unicode encoding form. +\indextext{character set|)} + +\rSec2[lex.universal.char]{Universal character names} \begin{bnf} -\nontermdef{n-char} \textnormal{one of}\br +\nontermdef{n-char}\br \textnormal{any member of the translation character set except the \unicode{007d}{right curly bracket} or new-line character} \end{bnf} @@ -364,6 +428,22 @@ named-universal-character \end{bnf} +\pnum +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} +(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. +\begin{note} +A sequence of characters resembling a \grammarterm{universal-character-name} in an +\grammarterm{r-char-sequence}\iref{lex.string} does not form a +\grammarterm{universal-character-name}. +\end{note} + \pnum A \grammarterm{universal-character-name} of the form \tcode{\textbackslash u} \grammarterm{hex-quad}, @@ -391,104 +471,49 @@ None of these names or aliases have leading or trailing spaces. \end{note} -\pnum -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} -(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. -\begin{note} -A sequence of characters resembling a \grammarterm{universal-character-name} in an -\grammarterm{r-char-sequence}\iref{lex.string} does not form a -\grammarterm{universal-character-name}. -\end{note} - -\pnum -The \defnadj{basic literal}{character set} consists of -all characters of the basic character set, -plus the control characters specified in \tref{lex.charset.literal}. - -\begin{floattable}{Additional control characters}{lex.charset.literal}{ll} -\topline -\ohdrx{2}{character} \\ \capsep -\ucode{0000} & \uname{null} \\ -\ucode{0007} & \uname{alert} \\ -\ucode{0008} & \uname{backspace} \\ -\ucode{000d} & \uname{carriage return} \\ -\end{floattable} - -\pnum -A \defn{code unit} is an integer value -of character type\iref{basic.fundamental}. -Characters in a \grammarterm{character-literal} -other than a multicharacter or non-encodable character literal or -in a \grammarterm{string-literal} are encoded as -a sequence of one or more code units, as determined -by the \grammarterm{encoding-prefix}\iref{lex.ccon,lex.string}; -this is termed the respective \defnadj{literal}{encoding}. -The \defnadj{ordinary literal}{encoding} is -the encoding applied to an ordinary character or string literal. -The \defnadj{wide literal}{encoding} is the encoding applied -to a wide character or string literal. +\rSec1[lex.comment]{Comments} \pnum -A literal encoding or a locale-specific encoding of one of -the execution character sets\iref{character.seq} -encodes each element of the basic literal character set as -a single code unit with non-negative value, -distinct from the code unit for any other such element. +\indextext{comment|(}% +\indextext{comment!\tcode{/*} \tcode{*/}}% +\indextext{comment!\tcode{//}}% +The characters \tcode{/*} start a comment, which terminates with the +characters \tcode{*/}. These comments do not nest. +\indextext{comment!\tcode{//}}% +The characters \tcode{//} start a comment, which terminates immediately before the +next new-line character. If there is a form-feed or a vertical-tab +character in such a comment, only whitespace characters shall appear +between it and the new-line that terminates the comment; no diagnostic +is required. \begin{note} -A character not in the basic literal character set -can be encoded with more than one code unit; -the value of such a code unit can be the same as -that of a code unit for an element of the basic literal character set. +The comment characters \tcode{//}, \tcode{/*}, +and \tcode{*/} have no special meaning within a \tcode{//} comment and +are treated just like other characters. Similarly, the comment +characters \tcode{//} and \tcode{/*} have no special meaning within a +\tcode{/*} comment. \end{note} -\indextext{character!null}% -\indextext{wide-character!null}% -The \unicode{0000}{null} character is encoded as the value \tcode{0}. -No other element of the translation character set -is encoded with a code unit of value \tcode{0}. -The code unit value of each decimal digit character after the digit \tcode{0} (\ucode{0030}) -shall be one greater than the value of the previous. -The ordinary and wide literal encodings are otherwise -\impldef{ordinary and wide literal encodings}. -\indextext{UTF-8}% -\indextext{UTF-16}% -\indextext{UTF-32}% -For a UTF-8, UTF-16, or UTF-32 literal, -the implementation shall encode -the Unicode scalar value -corresponding to each character of the translation character set -as specified in the Unicode Standard -for the respective Unicode encoding form. -\indextext{character set|)} +\indextext{comment|)} -\rSec1[lex.pptoken]{Preprocessing tokens} +\rSec1[lex.pptokenize]{Preprocessor tokenization} +\rSec2[lex.pptoken]{Preprocessing tokens} \indextext{token!preprocessing|(}% \begin{bnf} \nontermdef{preprocessing-token}\br - header-name\br import-keyword\br module-keyword\br export-keyword\br - identifier\br + header-name\br pp-number\br + preprocessing-op-or-punc\br + identifier\br character-literal\br user-defined-character-literal\br string-literal\br user-defined-string-literal\br - preprocessing-op-or-punc\br \textnormal{each non-whitespace character that cannot be one of the above} \end{bnf} -\pnum -Each preprocessing token that is converted to a token\iref{lex.token} -shall have the lexical form of a keyword, an identifier, a literal, -or an operator or punctuator. - \pnum A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. @@ -523,6 +548,22 @@ between the quotation characters in a character literal or string literal. +\pnum +Each preprocessing token that is converted to a token\iref{lex.token} +shall have the lexical form of a keyword, an identifier, a literal, +or an operator or punctuator. + +\pnum +The \grammarterm{import-keyword} is produced +by processing an \keyword{import} directive\iref{cpp.import}, +the \grammarterm{module-keyword} is produced +by preprocessing a \keyword{module} directive\iref{cpp.module}, and +the \grammarterm{export-keyword} is produced +by preprocessing either of the previous two directives. +\begin{note} +None has any observable spelling. +\end{note} + \pnum If the input stream has been parsed into preprocessing tokens up to a given character: @@ -562,6 +603,7 @@ \end{itemize} \end{itemize} +\pnum \begin{example} \begin{codeblock} #define R "x" @@ -569,17 +611,6 @@ \end{codeblock} \end{example} -\pnum -The \grammarterm{import-keyword} is produced -by preprocessing an \keyword{import} directive\iref{cpp.import}, -the \grammarterm{module-keyword} is produced -by preprocessing a \keyword{module} directive\iref{cpp.module}, and -the \grammarterm{export-keyword} is produced -by preprocessing either of the previous two directives. -\begin{note} -None has any observable spelling. -\end{note} - \pnum \begin{example} The program fragment \tcode{0xe+foo} is parsed as a @@ -602,125 +633,25 @@ \end{example} \indextext{token!preprocessing|)} -\rSec1[lex.digraph]{Alternative tokens} - -\pnum -\indextext{token!alternative|(}% -Alternative token representations are provided for some operators and -punctuators. -\begin{footnote} -\indextext{digraph}% -These include ``digraphs'' and additional reserved words. The term -``digraph'' (token consisting of two characters) is not perfectly -descriptive, since one of the alternative \grammarterm{preprocessing-token}s is -\tcode{\%:\%:} and of course several primary tokens contain two -characters. Nonetheless, those alternative tokens that aren't lexical -keywords are colloquially known as ``digraphs''. -\end{footnote} - -\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} -The set of alternative tokens is defined in -\tref{lex.digraph}. +\rSec2[lex.header]{Header names} -\begin{tokentable}{Alternative tokens}{lex.digraph}{Alternative}{Primary} -\tcode{<\%} & \tcode{\{} & -\keyword{and} & \tcode{\&\&} & -\keyword{and_eq} & \tcode{\&=} \\ \rowsep -\tcode{\%>} & \tcode{\}} & -\keyword{bitor} & \tcode{|} & -\keyword{or_eq} & \tcode{|=} \\ \rowsep -\tcode{<:} & \tcode{[} & -\keyword{or} & \tcode{||} & -\keyword{xor_eq} & \tcode{\caret=} \\ \rowsep -\tcode{:>} & \tcode{]} & -\keyword{xor} & \tcode{\caret} & -\keyword{not} & \tcode{!} \\ \rowsep -\tcode{\%:} & \tcode{\#} & -\keyword{compl} & \tcode{\~} & -\keyword{not_eq} & \tcode{!=} \\ \rowsep -\tcode{\%:\%:} & \tcode{\#\#} & -\keyword{bitand} & \tcode{\&} & - & \\ -\end{tokentable}% -\indextext{token!alternative|)} +\indextext{header!name|(}% +\begin{bnf} +\microtypesetup{protrusion=false}\obeyspaces +\nontermdef{header-name}\br + \terminal{<} h-char-sequence \terminal{>}\br + \terminal{"} q-char-sequence \terminal{"} +\end{bnf} -\rSec1[lex.token]{Tokens} +\begin{bnf} +\nontermdef{h-char-sequence}\br + h-char\br + h-char-sequence h-char +\end{bnf} -\indextext{token|(}% \begin{bnf} -\nontermdef{token}\br - identifier\br - keyword\br - literal\br - operator-or-punctuator -\end{bnf} - -\pnum -\indextext{\idxgram{token}}% -There are five kinds of tokens: identifiers, keywords, literals,% -\begin{footnote} -Literals include strings and character and numeric literals. -\end{footnote} -operators, and other separators. -\indextext{whitespace}% -Blanks, horizontal and vertical tabs, newlines, formfeeds, and comments -(collectively, ``whitespace''), as described below, are ignored except -as they serve to separate tokens. -\begin{note} -Whitespace can separate otherwise adjacent identifiers, keywords, numeric -literals, and alternative tokens containing alphabetic characters. -\end{note} -\indextext{token|)} - -\rSec1[lex.comment]{Comments} - -\pnum -\indextext{comment|(}% -\indextext{comment!\tcode{/*} \tcode{*/}}% -\indextext{comment!\tcode{//}}% -The characters \tcode{/*} start a comment, which terminates with the -characters \tcode{*/}. These comments do not nest. -\indextext{comment!\tcode{//}}% -The characters \tcode{//} start a comment, which terminates immediately before the -next new-line character. If there is a form-feed or a vertical-tab -character in such a comment, only whitespace characters shall appear -between it and the new-line that terminates the comment; no diagnostic -is required. -\begin{note} -The comment characters \tcode{//}, \tcode{/*}, -and \tcode{*/} have no special meaning within a \tcode{//} comment and -are treated just like other characters. Similarly, the comment -characters \tcode{//} and \tcode{/*} have no special meaning within a -\tcode{/*} comment. -\end{note} -\indextext{comment|)} - -\rSec1[lex.header]{Header names} - -\indextext{header!name|(}% -\begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces -\nontermdef{header-name}\br - \terminal{<} h-char-sequence \terminal{>}\br - \terminal{"} q-char-sequence \terminal{"} -\end{bnf} - -\begin{bnf} -\nontermdef{h-char-sequence}\br - h-char\br - h-char-sequence h-char -\end{bnf} - -\begin{bnf} -\nontermdef{h-char}\br - \textnormal{any member of the translation character set except new-line and \unicode{003e}{greater-than sign}} +\nontermdef{h-char}\br + \textnormal{any member of the translation character set except new-line and \unicode{003e}{greater-than sign}} \end{bnf} \begin{bnf} @@ -762,7 +693,7 @@ \end{footnote} \indextext{header!name|)} -\rSec1[lex.ppnumber]{Preprocessing numbers} +\rSec2[lex.ppnumber]{Preprocessing numbers} \indextext{number!preprocessing|(}% \begin{bnf} @@ -791,1262 +722,1346 @@ a \grammarterm{floating-point-literal} token.% \indextext{number!preprocessing|)} -\rSec1[lex.name]{Identifiers} - -\indextext{identifier|(}% -\begin{bnf} -\nontermdef{identifier}\br - identifier-start\br - identifier identifier-continue -\end{bnf} +\rSec2[lex.operators]{Operators and punctuators} -\begin{bnf} -\nontermdef{identifier-start}\br - nondigit\br - \textnormal{an element of the translation character set with the Unicode property XID_Start} -\end{bnf} +\pnum +\indextext{operator|(}% +\indextext{punctuator|(}% +The lexical representation of \Cpp{} programs includes a number of +preprocessing tokens that are used in the syntax of the preprocessor or +are converted into tokens for operators and punctuators: \begin{bnf} -\nontermdef{identifier-continue}\br - digit\br - nondigit\br - \textnormal{an element of the translation character set with the Unicode property XID_Continue} +\nontermdef{preprocessing-op-or-punc}\br + preprocessing-operator\br + operator-or-punctuator \end{bnf} \begin{bnf} -\nontermdef{nondigit} \textnormal{one of}\br - \terminal{a b c d e f g h i j k l m}\br - \terminal{n o p q r s t u v w x y z}\br - \terminal{A B C D E F G H I J K L M}\br - \terminal{N O P Q R S T U V W X Y Z _} +%% Ed. note: character protrusion would misalign various operators. +\microtypesetup{protrusion=false}\obeyspaces +\nontermdef{preprocessing-operator} \textnormal{one of}\br + \terminal{\# \#\# \%: \%:\%:} \end{bnf} \begin{bnf} -\nontermdef{digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7 8 9} +\microtypesetup{protrusion=false}\obeyspaces +\nontermdef{operator-or-punctuator} \textnormal{one of}\br + \terminal{\{ \} [ ] ( )}\br + \terminal{<: :> <\% \%> ; : ...}\br + \terminal{? :: . .* -> ->* \~}\br + \terminal{! + - * / \% \caret{} \& |}\br + \terminal{= += -= *= /= \%= \caret{}= \&= |=}\br + \terminal{== != < > <= >= <=> \&\& ||}\br + \terminal{<< >> <<= >>= ++ -- ,}\br + \terminal{\keyword{and} \keyword{or} \keyword{xor} \keyword{not} \keyword{bitand} \keyword{bitor} \keyword{compl}}\br + \terminal{\keyword{and_eq} \keyword{or_eq} \keyword{xor_eq} \keyword{not_eq}} \end{bnf} \pnum -\indextext{name!length of}% -\indextext{name}% -\begin{note} -The character properties XID_Start and XID_Continue are Derived Core Properties -as described by \UAX{44} of the Unicode Standard. +\indextext{token!alternative|(}% +Alternative token representations are provided for some operators and +punctuators. \begin{footnote} -On systems in which linkers cannot accept extended -characters, an encoding of the \grammarterm{universal-character-name} can be used in -forming valid external identifiers. For example, some otherwise unused -character or sequence of characters can be used to encode the -\tcode{\textbackslash u} in a \grammarterm{universal-character-name}. Extended -characters can produce a long external identifier, but \Cpp{} does not -place a translation limit on significant characters for external -identifiers. +\indextext{digraph}% +These include ``digraphs'' and additional reserved words. The term +``digraph'' (token consisting of two characters) is not perfectly +descriptive, since one of the alternative \grammarterm{preprocessing-token}s is +\tcode{\%:\%:} and of course several primary tokens contain two +characters. Nonetheless, those alternative tokens that aren't lexical +keywords are colloquially known as ``digraphs''. \end{footnote} -\end{note} -The program is ill-formed -if an \grammarterm{identifier} does not conform to -Normalization Form C as specified in the Unicode Standard. -\begin{note} -Identifiers are case-sensitive. -\end{note} -\begin{note} -\ref{uaxid} compares the requirements of \UAX{31} of the Unicode Standard -with the \Cpp{} rules for identifiers. -\end{note} -\begin{note} -In translation phase 4, -\grammarterm{identifier} also includes -those \grammarterm{preprocessing-token}s\iref{lex.pptoken} -differentiated as keywords\iref{lex.key} -in the later translation phase 7\iref{lex.token}. -\end{note} - -\pnum -\indextext{\idxcode{import}}% -\indextext{\idxcode{final}}% -\indextext{\idxcode{module}}% -\indextext{\idxcode{override}}% -The identifiers in \tref{lex.name.special} have a special meaning when -appearing in a certain context. When referred to in the grammar, these identifiers -are used explicitly rather than using the \grammarterm{identifier} grammar production. -Unless otherwise specified, any ambiguity as to whether a given -\grammarterm{identifier} has a special meaning is resolved to interpret the -token as a regular \grammarterm{identifier}. +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} +The set of alternative tokens is defined in +\tref{lex.digraph}. -\begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special} -{llll} -\keyword{final} \\ -\columnbreak -\keyword{import} \\ -\columnbreak -\keyword{module} \\ -\columnbreak -\keyword{override} \\ -\end{multicolfloattable} +\begin{tokentable}{Alternative tokens}{lex.digraph}{Alternative}{Primary} +\tcode{<\%} & \tcode{\{} & +\keyword{and} & \tcode{\&\&} & +\keyword{and_eq} & \tcode{\&=} \\ \rowsep +\tcode{\%>} & \tcode{\}} & +\keyword{bitor} & \tcode{|} & +\keyword{or_eq} & \tcode{|=} \\ \rowsep +\tcode{<:} & \tcode{[} & +\keyword{or} & \tcode{||} & +\keyword{xor_eq} & \tcode{\caret=} \\ \rowsep +\tcode{:>} & \tcode{]} & +\keyword{xor} & \tcode{\caret} & +\keyword{not} & \tcode{!} \\ \rowsep +\tcode{\%:} & \tcode{\#} & +\keyword{compl} & \tcode{\~} & +\keyword{not_eq} & \tcode{!=} \\ \rowsep +\tcode{\%:\%:} & \tcode{\#\#} & +\keyword{bitand} & \tcode{\&} & + & \\ +\end{tokentable}% +\indextext{token!alternative|)} \pnum -\indextext{\idxcode{_}|see{character, underscore}}% -\indextext{character!underscore!in identifier}% -\indextext{reserved identifier}% -In addition, some identifiers -appearing as a \grammarterm{token} or \grammarterm{preprocessing-token} -are reserved for use by \Cpp{} -implementations and shall -not be used otherwise; no diagnostic is required. -\begin{itemize} -\item -Each identifier that contains a double underscore -\tcode{\unun} -\indextext{character!underscore}% -or begins with an underscore followed by -an uppercase letter, -other than those specified in this document -(for example, \xname{cplusplus}\iref{cpp.predefined}), -\indextext{uppercase}% -is reserved to the implementation for any use. -\item -Each identifier that begins with an underscore is -\indextext{character!underscore}% -reserved to the implementation for use as a name in the global namespace.% -\indextext{namespace!global} -\end{itemize}% -\indextext{identifier|)} +Each \grammarterm{operator-or-punctuator} is converted to a single token +in translation phase 7\iref{lex.phases}.% +\indextext{punctuator|)}% +\indextext{operator|)} -\rSec1[lex.key]{Keywords} +\rSec2[lex.ccon]{Character literals} +\indextext{literal!character}% \begin{bnf} -\nontermdef{keyword}\br - \textnormal{any identifier listed in \tref{lex.key}}\br - \grammarterm{import-keyword}\br - \grammarterm{module-keyword}\br - \grammarterm{export-keyword} +\nontermdef{character-literal}\br + \opt{encoding-prefix} \terminal{'} c-char-sequence \terminal{'} \end{bnf} -\pnum -\indextext{keyword|(}% -The identifiers shown in \tref{lex.key} are reserved for use -as keywords (that is, they are unconditionally treated as keywords in -phase 7) except in an \grammarterm{attribute-token}\iref{dcl.attr.grammar}. -\begin{note} -The \keyword{register} keyword is unused but -is reserved for future use. -\end{note} - -\begin{multicolfloattable}{Keywords}{lex.key} -{lllll} -\keyword{alignas} \\ -\keyword{alignof} \\ -\keyword{asm} \\ -\keyword{auto} \\ -\keyword{bool} \\ -\keyword{break} \\ -\keyword{case} \\ -\keyword{catch} \\ -\keyword{char} \\ -\keyword{char8_t} \\ -\keyword{char16_t} \\ -\keyword{char32_t} \\ -\keyword{class} \\ -\keyword{concept} \\ -\keyword{const} \\ -\keyword{consteval} \\ -\keyword{constexpr} \\ -\columnbreak -\keyword{constinit} \\ -\keyword{const_cast} \\ -\keyword{continue} \\ -\keyword{co_await} \\ -\keyword{co_return} \\ -\keyword{co_yield} \\ -\keyword{decltype} \\ -\keyword{default} \\ -\keyword{delete} \\ -\keyword{do} \\ -\keyword{double} \\ -\keyword{dynamic_cast} \\ -\keyword{else} \\ -\keyword{enum} \\ -\keyword{explicit} \\ -\keyword{export} \\ -\keyword{extern} \\ -\columnbreak -\keyword{false} \\ -\keyword{float} \\ -\keyword{for} \\ -\keyword{friend} \\ -\keyword{goto} \\ -\keyword{if} \\ -\keyword{inline} \\ -\keyword{int} \\ -\keyword{long} \\ -\keyword{mutable} \\ -\keyword{namespace} \\ -\keyword{new} \\ -\keyword{noexcept} \\ -\keyword{nullptr} \\ -\keyword{operator} \\ -\keyword{private} \\ -\keyword{protected} \\ -\columnbreak -\keyword{public} \\ -\keyword{register} \\ -\keyword{reinterpret_cast} \\ -\keyword{requires} \\ -\keyword{return} \\ -\keyword{short} \\ -\keyword{signed} \\ -\keyword{sizeof} \\ -\keyword{static} \\ -\keyword{static_assert} \\ -\keyword{static_cast} \\ -\keyword{struct} \\ -\keyword{switch} \\ -\keyword{template} \\ -\keyword{this} \\ -\keyword{thread_local} \\ -\keyword{throw} \\ -\columnbreak -\keyword{true} \\ -\keyword{try} \\ -\keyword{typedef} \\ -\keyword{typeid} \\ -\keyword{typename} \\ -\keyword{union} \\ -\keyword{unsigned} \\ -\keyword{using} \\ -\keyword{virtual} \\ -\keyword{void} \\ -\keyword{volatile} \\ -\keyword{wchar_t} \\ -\keyword{while} \\ -\end{multicolfloattable} - -\pnum -Furthermore, the alternative representations shown in -\tref{lex.key.digraph} for certain operators and -punctuators\iref{lex.digraph} are reserved and shall not be used -otherwise. - -\begin{floattable}{Alternative representations}{lex.key.digraph} -{llllll} -\topline -\keyword{and} & \keyword{and_eq} & \keyword{bitand} & \keyword{bitor} & \keyword{compl} & \keyword{not} \\ -\keyword{not_eq} & \keyword{or} & \keyword{or_eq} & \keyword{xor} & \keyword{xor_eq} & \\ -\end{floattable}% -\indextext{keyword|)}% - - -\rSec1[lex.operators]{Operators and punctuators} - -\pnum -\indextext{operator|(}% -\indextext{punctuator|(}% -The lexical representation of \Cpp{} programs includes a number of -preprocessing tokens that are used in the syntax of the preprocessor or -are converted into tokens for operators and punctuators: - -\begin{bnf} -\nontermdef{preprocessing-op-or-punc}\br - preprocessing-operator\br - operator-or-punctuator -\end{bnf} +\begin{bnf} +\nontermdef{encoding-prefix} \textnormal{one of}\br + \terminal{u8}\quad\terminal{u}\quad\terminal{U}\quad\terminal{L} +\end{bnf} \begin{bnf} -%% Ed. note: character protrusion would misalign various operators. -\microtypesetup{protrusion=false}\obeyspaces -\nontermdef{preprocessing-operator} \textnormal{one of}\br - \terminal{\# \#\# \%: \%:\%:} +\nontermdef{c-char-sequence}\br + c-char\br + c-char-sequence c-char \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces -\nontermdef{operator-or-punctuator} \textnormal{one of}\br - \terminal{\{ \} [ ] ( )}\br - \terminal{<: :> <\% \%> ; : ...}\br - \terminal{? :: . .* -> ->* \~}\br - \terminal{! + - * / \% \caret{} \& |}\br - \terminal{= += -= *= /= \%= \caret{}= \&= |=}\br - \terminal{== != < > <= >= <=> \&\& ||}\br - \terminal{<< >> <<= >>= ++ -- ,}\br - \terminal{\keyword{and} \keyword{or} \keyword{xor} \keyword{not} \keyword{bitand} \keyword{bitor} \keyword{compl}}\br - \terminal{\keyword{and_eq} \keyword{or_eq} \keyword{xor_eq} \keyword{not_eq}} +\nontermdef{c-char}\br + basic-c-char\br + escape-sequence\br + universal-character-name \end{bnf} -Each \grammarterm{operator-or-punctuator} is converted to a single token -in translation phase 7\iref{lex.phases}.% -\indextext{punctuator|)}% -\indextext{operator|)} - -\rSec1[lex.literal]{Literals}% -\indextext{literal|(} - -\rSec2[lex.literal.kinds]{Kinds of literals} - -\pnum -\indextext{constant}% -\indextext{literal!constant}% -There are several kinds of literals. -\begin{footnote} -The term ``literal'' generally designates, in this -document, those tokens that are called ``constants'' in C. -\end{footnote} - \begin{bnf} -\nontermdef{literal}\br - integer-literal\br - character-literal\br - floating-point-literal\br - string-literal\br - boolean-literal\br - pointer-literal\br - user-defined-literal +\nontermdef{basic-c-char}\br + \textnormal{any member of the translation character set except the \unicode{0027}{apostrophe},}\br + \bnfindent\textnormal{\unicode{005c}{reverse solidus}, or new-line character} \end{bnf} -\begin{note} -When appearing as an \grammarterm{expression}, -a literal has a type and a value category\iref{expr.prim.literal}. -\end{note} -\rSec2[lex.icon]{Integer literals} - -\indextext{literal!integer}% \begin{bnf} -\nontermdef{integer-literal}\br - binary-literal \opt{integer-suffix}\br - octal-literal \opt{integer-suffix}\br - decimal-literal \opt{integer-suffix}\br - hexadecimal-literal \opt{integer-suffix} +\nontermdef{escape-sequence}\br + simple-escape-sequence\br + numeric-escape-sequence\br + conditional-escape-sequence \end{bnf} \begin{bnf} -\nontermdef{binary-literal}\br - \terminal{0b} binary-digit\br - \terminal{0B} binary-digit\br - binary-literal \opt{\terminal{'}} binary-digit +\nontermdef{simple-escape-sequence}\br + \terminal{\textbackslash} simple-escape-sequence-char \end{bnf} \begin{bnf} -\nontermdef{octal-literal}\br - \terminal{0}\br - octal-literal \opt{\terminal{'}} octal-digit +\nontermdef{simple-escape-sequence-char} \textnormal{one of}\br + \terminal{' " ? \textbackslash{} a b f n r t v} \end{bnf} \begin{bnf} -\nontermdef{decimal-literal}\br - nonzero-digit\br - decimal-literal \opt{\terminal{'}} digit +\nontermdef{numeric-escape-sequence}\br + octal-escape-sequence\br + hexadecimal-escape-sequence \end{bnf} \begin{bnf} -\nontermdef{hexadecimal-literal}\br - hexadecimal-prefix hexadecimal-digit-sequence +\nontermdef{simple-octal-digit-sequence}\br + octal-digit\br + simple-octal-digit-sequence octal-digit \end{bnf} \begin{bnf} -\nontermdef{binary-digit} \textnormal{one of}\br - \terminal{0 1} +\nontermdef{octal-escape-sequence}\br + \terminal{\textbackslash} octal-digit\br + \terminal{\textbackslash} octal-digit octal-digit\br + \terminal{\textbackslash} octal-digit octal-digit octal-digit\br + \terminal{\textbackslash o\{} simple-octal-digit-sequence \terminal{\}}\br \end{bnf} \begin{bnf} -\nontermdef{octal-digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7} +\nontermdef{hexadecimal-escape-sequence}\br + \terminal{\textbackslash x} simple-hexadecimal-digit-sequence\br + \terminal{\textbackslash x\{} simple-hexadecimal-digit-sequence \terminal{\}} \end{bnf} \begin{bnf} -\nontermdef{nonzero-digit} \textnormal{one of}\br - \terminal{1 2 3 4 5 6 7 8 9} +\nontermdef{conditional-escape-sequence}\br + \terminal{\textbackslash} conditional-escape-sequence-char \end{bnf} \begin{bnf} -\nontermdef{hexadecimal-prefix} \textnormal{one of}\br - \terminal{0x 0X} +\nontermdef{conditional-escape-sequence-char}\br + \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{N}, \terminal{o}, \terminal{u}, \terminal{U}, or \terminal{x}} \end{bnf} -\begin{bnf} -\nontermdef{hexadecimal-digit-sequence}\br - hexadecimal-digit\br - hexadecimal-digit-sequence \opt{\terminal{'}} hexadecimal-digit -\end{bnf} +\pnum +\indextext{literal!character}% +\indextext{literal!\idxcode{char8_t}}% +\indextext{literal!\idxcode{char16_t}}% +\indextext{literal!\idxcode{char32_t}}% +\indextext{literal!type of character}% +\indextext{type!\idxcode{char8_t}}% +\indextext{type!\idxcode{char16_t}}% +\indextext{type!\idxcode{char32_t}}% +\indextext{wide-character}% +\indextext{type!\idxcode{wchar_t}}% +A \defnadj{multicharacter}{literal} is a \grammarterm{character-literal} +whose \grammarterm{c-char-sequence} consists of +more than one \grammarterm{c-char}. +A multicharacter literal shall not have an \grammarterm{encoding-prefix}. +If a multicharacter literal contains a \grammarterm{c-char} +that is not encodable as a single code unit in the ordinary literal encoding, +the program is ill-formed. +Multicharacter literals are conditionally-supported. -\begin{bnf} -\nontermdef{hexadecimal-digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7 8 9}\br - \terminal{a b c d e f}\br - \terminal{A B C D E F} -\end{bnf} +\pnum +The kind of a \grammarterm{character-literal}, +its type, and its associated character encoding\iref{lex.charset} +are determined by +its \grammarterm{encoding-prefix} and its \grammarterm{c-char-sequence} +as defined by \tref{lex.ccon.literal}. -\begin{bnf} -\nontermdef{integer-suffix}\br - unsigned-suffix \opt{long-suffix} \br - unsigned-suffix \opt{long-long-suffix} \br - unsigned-suffix \opt{size-suffix} \br - long-suffix \opt{unsigned-suffix} \br - long-long-suffix \opt{unsigned-suffix} \br - size-suffix \opt{unsigned-suffix} +\begin{floattable}{Character literals}{lex.ccon.literal} +{l|l|l|l|l} +\topline +\lhdr{Encoding} & \chdr{Kind} & \chdr{Type} & \chdr{Associated char-} & \rhdr{Example} \\ +\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{acter encoding} & \\ +\capsep +none & +\defnx{ordinary character literal}{literal!character!ordinary} & +\keyword{char} & +ordinary literal & +\tcode{'v'} \\ \cline{2-3}\cline{5-5} + & +multicharacter literal & +\keyword{int} & +encoding & +\tcode{'abcd'} \\ \hline +\tcode{L} & +\defnx{wide character literal}{literal!character!wide} & +\keyword{wchar_t} & +wide literal & +\tcode{L'w'} \\ + & & & encoding & \\ \hline +\tcode{u8} & +\defnx{UTF-8 character literal}{literal!character!UTF-8} & +\keyword{char8_t} & +UTF-8 & +\tcode{u8'x'} \\ \hline +\tcode{u} & +\defnx{UTF-16 character literal}{literal!character!UTF-16} & +\keyword{char16_t} & +UTF-16 & +\tcode{u'y'} \\ \hline +\tcode{U} & +\defnx{UTF-32 character literal}{literal!character!UTF-32} & +\keyword{char32_t} & +UTF-32 & +\tcode{U'z'} \\ +\end{floattable} + +\pnum +In translation phase 4, +the value of a \grammarterm{character-literal} is determined +using the range of representable values +of the \grammarterm{character-literal}'s type in translation phase 7. +A multicharacter literal has an +\impldef{value of non-encodable character literal or multicharacter literal} +value. +The value of any other kind of \grammarterm{character-literal} +is determined as follows: +\begin{itemize} +\item +A \grammarterm{character-literal} with +a \grammarterm{c-char-sequence} consisting of a single +\grammarterm{basic-c-char}, +\grammarterm{simple-escape-sequence}, or +\grammarterm{universal-character-name} +is the code unit value of the specified character +as encoded in the literal's associated character encoding. +If the specified character lacks +representation in the literal's associated character encoding or +if it cannot be encoded as a single code unit, +then the program is ill-formed. +\item +A \grammarterm{character-literal} with +a \grammarterm{c-char-sequence} consisting of +a single \grammarterm{numeric-escape-sequence} +has a value as follows: +\begin{itemize} +\item +Let $v$ be the integer value represented by +the octal number comprising +the sequence of \grammarterm{octal-digit}{s} in +an \grammarterm{octal-escape-sequence} or by +the hexadecimal number comprising +the sequence of \grammarterm{hexadecimal-digit}{s} in +a \grammarterm{hexadecimal-escape-sequence}. +\item +If $v$ does not exceed +the range of representable values of the \grammarterm{character-literal}'s type, +then the value is $v$. +\item +Otherwise, +if the \grammarterm{character-literal}'s \grammarterm{encoding-prefix} +is absent or \tcode{L}, and +$v$ does not exceed the range of representable values of the corresponding unsigned type for the underlying type of the \grammarterm{character-literal}'s type, +then the value is the unique value of the \grammarterm{character-literal}'s type \tcode{T} that is congruent to $v$ modulo $2^N$, where $N$ is the width of \tcode{T}. +\item +Otherwise, the program is ill-formed. +\end{itemize} +\item +A \grammarterm{character-literal} with +a \grammarterm{c-char-sequence} consisting of +a single \grammarterm{conditional-escape-sequence} +is conditionally-supported and +has an \impldef{value of \grammarterm{conditional-escape-sequence}} value. +\end{itemize} + +\pnum +\indextext{backslash character}% +\indextext{\idxcode{\textbackslash}|see{backslash character}}% +\indextext{escape character|see{backslash character}}% +The character specified by a \grammarterm{simple-escape-sequence} +is specified in \tref{lex.ccon.esc}. +\begin{note} +Using an escape sequence for a question mark +is supported for compatibility with \CppXIV{} and C. +\end{note} + +\begin{floattable}{Simple escape sequences}{lex.ccon.esc} +{lll} +\topline +\lhdrx{2}{character} & \rhdr{\grammarterm{simple-escape-sequence}} \\ \capsep +\ucode{000a} & \uname{line feed} & \tcode{\textbackslash n} \\ +\ucode{0009} & \uname{character tabulation} & \tcode{\textbackslash t} \\ +\ucode{000b} & \uname{line tabulation} & \tcode{\textbackslash v} \\ +\ucode{0008} & \uname{backspace} & \tcode{\textbackslash b} \\ +\ucode{000d} & \uname{carriage return} & \tcode{\textbackslash r} \\ +\ucode{000c} & \uname{form feed} & \tcode{\textbackslash f} \\ +\ucode{0007} & \uname{alert} & \tcode{\textbackslash a} \\ +\ucode{005c} & \uname{reverse solidus} & \tcode{\textbackslash\textbackslash} \\ +\ucode{003f} & \uname{question mark} & \tcode{\textbackslash ?} \\ +\ucode{0027} & \uname{apostrophe} & \tcode{\textbackslash '} \\ +\ucode{0022} & \uname{quotation mark} & \tcode{\textbackslash "} \\ +\end{floattable} + +\rSec2[lex.string]{String literals} + +\indextext{literal!string}% +\begin{bnf} +\nontermdef{string-literal}\br + \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br + \opt{encoding-prefix} \terminal{R} raw-string \end{bnf} \begin{bnf} -\nontermdef{unsigned-suffix} \textnormal{one of}\br - \terminal{u U} +\nontermdef{s-char-sequence}\br + s-char\br + s-char-sequence s-char \end{bnf} \begin{bnf} -\nontermdef{long-suffix} \textnormal{one of}\br - \terminal{l L} +\nontermdef{s-char}\br + basic-s-char\br + escape-sequence\br + universal-character-name \end{bnf} \begin{bnf} -\nontermdef{long-long-suffix} \textnormal{one of}\br - \terminal{ll LL} +\nontermdef{basic-s-char}\br + \textnormal{any member of the translation character set except the \unicode{0022}{quotation mark},}\br + \bnfindent\textnormal{\unicode{005c}{reverse solidus}, or new-line character} \end{bnf} \begin{bnf} -\nontermdef{size-suffix} \textnormal{one of}\br - \terminal{z Z} +\nontermdef{raw-string}\br + \terminal{"} \opt{d-char-sequence} \terminal{(} \opt{r-char-sequence} \terminal{)} \opt{d-char-sequence} \terminal{"} \end{bnf} -\pnum -\indextext{literal!\idxcode{unsigned}}% -\indextext{literal!\idxcode{long}}% -\indextext{literal!base of integer}% -In an \grammarterm{integer-literal}, -the sequence of -\grammarterm{binary-digit}s, -\grammarterm{octal-digit}s, -\grammarterm{digit}s, or -\grammarterm{hexadecimal-digit}s -is interpreted as a base $N$ integer as shown in table \tref{lex.icon.base}; -the lexically first digit of the sequence of digits is the most significant. -\begin{note} -The prefix and any optional separating single quotes are ignored -when determining the value. -\end{note} +\begin{bnf} +\nontermdef{r-char-sequence}\br + r-char\br + r-char-sequence r-char +\end{bnf} -\begin{simpletypetable} -{Base of \grammarterm{integer-literal}{s}} -{lex.icon.base} -{lr} -\topline -\lhdr{Kind of \grammarterm{integer-literal}} & \rhdr{base $N$} \\ \capsep -\grammarterm{binary-literal} & 2 \\ -\grammarterm{octal-literal} & 8 \\ -\grammarterm{decimal-literal} & 10 \\ -\grammarterm{hexadecimal-literal} & 16 \\ -\end{simpletypetable} +\begin{bnf} +\nontermdef{r-char}\br + \textnormal{any member of the translation character set, except a \unicode{0029}{right parenthesis} followed by}\br + \bnfindent\textnormal{the initial \grammarterm{d-char-sequence} (which may be empty) followed by a \unicode{0022}{quotation mark}} +\end{bnf} -\pnum -The \grammarterm{hexadecimal-digit}s -\tcode{a} through \tcode{f} and \tcode{A} through \tcode{F} -have decimal values ten through fifteen. -\begin{example} -The number twelve can be written \tcode{12}, \tcode{014}, -\tcode{0XC}, or \tcode{0b1100}. The \grammarterm{integer-literal}s \tcode{1048576}, -\tcode{1'048'576}, \tcode{0X100000}, \tcode{0x10'0000}, and -\tcode{0'004'000'000} all have the same value. -\end{example} +\begin{bnf} +\nontermdef{d-char-sequence}\br + d-char\br + d-char-sequence d-char +\end{bnf} + +\begin{bnf} +\nontermdef{d-char}\br + \textnormal{any member of the basic character set except:}\br + \bnfindent\textnormal{\unicode{0020}{space}, \unicode{0028}{left parenthesis}, \unicode{0029}{right parenthesis}, \unicode{005c}{reverse solidus},}\br + \bnfindent\textnormal{\unicode{0009}{character tabulation}, \unicode{000b}{line tabulation}, \unicode{000c}{form feed}, and new-line} +\end{bnf} \pnum -\indextext{literal!\idxcode{long}}% -\indextext{literal!\idxcode{unsigned}}% -\indextext{literal!integer}% -\indextext{literal!type of integer}% -\indextext{suffix!\idxcode{L}}% -\indextext{suffix!\idxcode{U}}% -\indextext{suffix!\idxcode{l}}% -\indextext{suffix!\idxcode{u}}% -The type of an \grammarterm{integer-literal} is -the first type in the list in \tref{lex.icon.type} -corresponding to its optional \grammarterm{integer-suffix} -in which its value can be represented. +\indextext{literal!string}% +\indextext{character string}% +\indextext{string!type of}% +\indextext{type!\idxcode{wchar_t}}% +\indextext{prefix!\idxcode{L}}% +\indextext{literal!string!\idxcode{char16_t}}% +\indextext{type!\idxcode{char16_t}}% +\indextext{literal!string!\idxcode{char32_t}}% +\indextext{type!\idxcode{char32_t}}% +The kind of a \grammarterm{string-literal}, +its type, and +its associated character encoding\iref{lex.charset} +are determined by its encoding prefix and sequence of +\grammarterm{s-char}s or \grammarterm{r-char}s +as defined by \tref{lex.string.literal} +where $n$ is the number of encoded code units as described below. -\begin{floattable}{Types of \grammarterm{integer-literal}s}{lex.icon.type}{l|l|l} +\begin{floattable}{String literals}{lex.string.literal} +{llp{2.6cm}p{2.3cm}p{4.7cm}} \topline -\lhdr{\grammarterm{integer-suffix}} & \chdr{\grammarterm{decimal-literal}} & \rhdr{\grammarterm{integer-literal} other than \grammarterm{decimal-literal}} \\ \capsep -none & - \tcode{int} & - \tcode{int}\\ - & - \tcode{long int} & - \tcode{unsigned int}\\ - & - \tcode{long long int} & - \tcode{long int}\\ - & - & - \tcode{unsigned long int}\\ - & - & - \tcode{long long int}\\ - & - & - \tcode{unsigned long long int}\\\hline -\tcode{u} or \tcode{U} & - \tcode{unsigned int} & - \tcode{unsigned int}\\ - & - \tcode{unsigned long int} & - \tcode{unsigned long int}\\ - & - \tcode{unsigned long long int} & - \tcode{unsigned long long int}\\\hline -\tcode{l} or \tcode{L} & - \tcode{long int} & - \tcode{long int}\\ - & - \tcode{long long int} & - \tcode{unsigned long int}\\ - & - & - \tcode{long long int}\\ - & - & - \tcode{unsigned long long int}\\\hline -Both \tcode{u} or \tcode{U} & - \tcode{unsigned long int} & - \tcode{unsigned long int}\\ -and \tcode{l} or \tcode{L} & - \tcode{unsigned long long int} & - \tcode{unsigned long long int}\\\hline -\tcode{ll} or \tcode{LL} & - \tcode{long long int} & - \tcode{long long int}\\ - & - & - \tcode{unsigned long long int}\\\hline -Both \tcode{u} or \tcode{U} & - \tcode{unsigned long long int} & - \tcode{unsigned long long int}\\ -and \tcode{ll} or \tcode{LL} & - & - \\\hline -\tcode{z} or \tcode{Z} & - the signed integer type corresponding & - the signed integer type \\ - & - \qquad to \tcode{std::size_t}\iref{support.types.layout} & - \qquad corresponding to \tcode{std::size_t} \\ - & - & - \tcode{std::size_t}\\\hline -Both \tcode{u} or \tcode{U} & - \tcode{std::size_t} & - \tcode{std::size_t} \\ -and \tcode{z} or \tcode{Z} & - & - \\ +\lhdr{Enco-} & \chdr{Kind} & \chdr{Type} & \chdr{Associated} & \rhdr{Examples} \\ +\lhdr{ding} & \chdr{} & \chdr{} & \chdr{character} & \rhdr{} \\ +\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{encoding} & \rhdr{} \\ +\capsep +none & +\defnx{ordinary string literal}{literal!string!ordinary} & +array of $n$\newline \tcode{\keyword{const} \keyword{char}} & +ordinary literal encoding & +\tcode{"ordinary string"}\newline +\tcode{R"(ordinary raw string)"} \\ +\tcode{L} & +\defnx{wide string literal}{literal!string!wide} & +array of $n$\newline \tcode{\keyword{const} \keyword{wchar_t}} & +wide literal\newline encoding & +\tcode{L"wide string"}\newline +\tcode{LR"w(wide raw string)w"} \\ +\tcode{u8} & +\defnx{UTF-8 string literal}{literal!string!UTF-8} & +array of $n$\newline \tcode{\keyword{const} \keyword{char8_t}} & +UTF-8 & +\tcode{u8"UTF-8 string"}\newline +\tcode{u8R"x(UTF-8 raw string)x"} \\ +\tcode{u} & +\defnx{UTF-16 string literal}{literal!string!UTF-16} & +array of $n$\newline \tcode{\keyword{const} \keyword{char16_t}} & +UTF-16 & +\tcode{u"UTF-16 string"}\newline +\tcode{uR"y(UTF-16 raw string)y"} \\ +\tcode{U} & +\defnx{UTF-32 string literal}{literal!string!UTF-32} & +array of $n$\newline \tcode{\keyword{const} \keyword{char32_t}} & +UTF-32 & +\tcode{U"UTF-32 string"}\newline +\tcode{UR"z(UTF-32 raw string)z"} \\ \end{floattable} \pnum -Except for \grammarterm{integer-literal}{s} containing -a \grammarterm{size-suffix}, -if the value of an \grammarterm{integer-literal} -cannot be represented by any type in its list and -an extended integer type\iref{basic.fundamental} can represent its value, -it may have that extended integer type. -If all of the types in the list for the \grammarterm{integer-literal} -are signed, -the extended integer type is signed. -If all of the types in the list for the \grammarterm{integer-literal} -are unsigned, -the extended integer type is unsigned. -If the list contains both signed and unsigned types, -the extended integer type may be signed or unsigned. -If an \grammarterm{integer-literal} -cannot be represented by any of the allowed types, -the program is ill-formed. +\indextext{literal!string!raw}% +A \grammarterm{string-literal} that has an \tcode{R} +\indextext{prefix!\idxcode{R}}% +in the prefix is a \defn{raw string literal}. The +\grammarterm{d-char-sequence} serves as a delimiter. The terminating +\grammarterm{d-char-sequence} of a \grammarterm{raw-string} is the same sequence of +characters as the initial \grammarterm{d-char-sequence}. A \grammarterm{d-char-sequence} +shall consist of at most 16 characters. + +\pnum \begin{note} -An \grammarterm{integer-literal} with a \tcode{z} or \tcode{Z} suffix -is ill-formed if it cannot be represented by \tcode{std::size_t}. +The characters \tcode{'('} and \tcode{')'} can appear in a +\grammarterm{raw-string}. Thus, \tcode{R"delimiter((a|b))delimiter"} is equivalent to +\tcode{"(a|b)"}. \end{note} -\rSec2[lex.ccon]{Character literals} +\pnum +\begin{note} +A source-file new-line in a raw string literal results in a new-line in the +resulting execution string literal. Assuming no +whitespace at the beginning of lines in the following example, the assert will succeed: +\begin{codeblock} +const char* p = R"(a\ +b +c)"; +assert(std::strcmp(p, "a\\\nb\nc") == 0); +\end{codeblock} +\end{note} -\indextext{literal!character}% +\pnum +\begin{example} +The raw string +\begin{codeblock} +R"a( +)\ +a" +)a" +\end{codeblock} +is equivalent to \tcode{"\textbackslash n)\textbackslash \textbackslash \textbackslash na\textbackslash"\textbackslash n"}. The raw string +\begin{codeblock} +R"(x = "\"y\"")" +\end{codeblock} +is equivalent to \tcode{"x = \textbackslash "\textbackslash\textbackslash\textbackslash "y\textbackslash\textbackslash\textbackslash "\textbackslash ""}. +\end{example} + +\pnum +\indextext{literal!narrow-character}% +Ordinary string literals and UTF-8 string literals are +also referred to as \defnx{narrow string literals}{literal!string!narrow}. + +\pnum +\indextext{concatenation!string}% +The \grammarterm{string-literal}{s} in +any sequence of adjacent \grammarterm{string-literal}{s} +shall have at most one unique \grammarterm{encoding-prefix} among them. +The common \grammarterm{encoding-prefix} of the sequence is +that \grammarterm{encoding-prefix}, if any. +\begin{note} +A \grammarterm{string-literal}'s rawness has +no effect on the determination of the common \grammarterm{encoding-prefix}. +\end{note} + +\pnum +In translation phase 6\iref{lex.phases}, +adjacent \grammarterm{string-literal}s are concatenated. +The lexical structure and grouping of +the contents of the individual \grammarterm{string-literal}s is retained. +\begin{example} +\begin{codeblock} +"\xA" "B" +\end{codeblock} +represents +the code unit \tcode{'\textbackslash xA'} and the character \tcode{'B'} +after concatenation +(and not the single code unit \tcode{'\textbackslash xAB'}). +Similarly, +\begin{codeblock} +R"(\u00)" "41" +\end{codeblock} +represents six characters, +starting with a backslash and ending with the digit \tcode{1} +(and not the single character \tcode{'A'} +specified by a \grammarterm{universal-character-name}). + +\tref{lex.string.concat} has some examples of valid concatenations. +\end{example} + +\begin{floattable}{String literal concatenations}{lex.string.concat} +{lll|lll|lll} +\topline +\multicolumn{2}{|c}{Source} & +Means & +\multicolumn{2}{c}{Source} & +Means & +\multicolumn{2}{c}{Source} & +Means \\ +\tcode{u"a"} & \tcode{u"b"} & \tcode{u"ab"} & +\tcode{U"a"} & \tcode{U"b"} & \tcode{U"ab"} & +\tcode{L"a"} & \tcode{L"b"} & \tcode{L"ab"} \\ +\tcode{u"a"} & \tcode{"b"} & \tcode{u"ab"} & +\tcode{U"a"} & \tcode{"b"} & \tcode{U"ab"} & +\tcode{L"a"} & \tcode{"b"} & \tcode{L"ab"} \\ +\tcode{"a"} & \tcode{u"b"} & \tcode{u"ab"} & +\tcode{"a"} & \tcode{U"b"} & \tcode{U"ab"} & +\tcode{"a"} & \tcode{L"b"} & \tcode{L"ab"} \\ +\end{floattable} + +\pnum +Evaluating a \grammarterm{string-literal} results in a string literal object +with static storage duration\iref{basic.stc}. +\begin{note} +String literal objects are potentially non-unique\iref{intro.object}. +Whether successive evaluations of a +\grammarterm{string-literal} yield the same or a different object is +unspecified. +\end{note} +\begin{note} +\indextext{literal!string!undefined change to}% +The effect of attempting to modify a string literal object is undefined. +\end{note} + +\pnum +\indextext{\idxcode{0}!string terminator}% +\indextext{\idxcode{0}!null character|see {character, null}}% +String literal objects are initialized with +the sequence of code unit values +corresponding to the \grammarterm{string-literal}'s sequence of +\grammarterm{s-char}s (originally from non-raw string literals) and +\grammarterm{r-char}s (originally from raw string literals), +plus a terminating \unicode{0000}{null} character, +in order as follows: +\begin{itemize} +\item +The sequence of characters denoted by each contiguous sequence of +\grammarterm{basic-s-char}s, +\grammarterm{r-char}s, +\grammarterm{simple-escape-sequence}s\iref{lex.ccon}, and +\grammarterm{universal-character-name}s\iref{lex.charset} +is encoded to a code unit sequence +using the \grammarterm{string-literal}'s associated character encoding. +If a character lacks representation in the associated character encoding, +then the program is ill-formed. +\begin{note} +No character lacks representation in any Unicode encoding form. +\end{note} +When encoding a stateful character encoding, +implementations should encode the first such sequence +beginning with the initial encoding state and +encode subsequent sequences +beginning with the final encoding state of the prior sequence. +\begin{note} +The encoded code unit sequence can differ from +the sequence of code units that would be obtained by +encoding each character independently. +\end{note} +\item +Each \grammarterm{numeric-escape-sequence}\iref{lex.ccon} +contributes a single code unit with a value as follows: +\begin{itemize} +\item +Let $v$ be the integer value represented by +the octal number comprising +the sequence of \grammarterm{octal-digit}{s} in +an \grammarterm{octal-escape-sequence} or by +the hexadecimal number comprising +the sequence of \grammarterm{hexadecimal-digit}{s} in +a \grammarterm{hexadecimal-escape-sequence}. +\item +If $v$ does not exceed the range of representable values of +the \grammarterm{string-literal}'s array element type, +then the value is $v$. +\item +Otherwise, +if the \grammarterm{string-literal}'s \grammarterm{encoding-prefix} +is absent or \tcode{L}, and +$v$ does not exceed the range of representable values of +the corresponding unsigned type for the underlying type of +the \grammarterm{string-literal}'s array element type, +then the value is the unique value of +the \grammarterm{string-literal}'s array element type \tcode{T} +that is congruent to $v$ modulo $2^N$, where $N$ is the width of \tcode{T}. +\item +Otherwise, the program is ill-formed. +\end{itemize} +When encoding a stateful character encoding, +these sequences should have no effect on encoding state. +\item +Each \grammarterm{conditional-escape-sequence}\iref{lex.ccon} +contributes an +\impldef{code unit sequence for \grammarterm{conditional-escape-sequence}} +code unit sequence. +When encoding a stateful character encoding, +it is +\impldef{effect of \grammarterm{conditional-escape-sequence} on encoding state} +what effect these sequences have on encoding state. +\end{itemize} + +\rSec2[lex.name]{Identifiers} + +\indextext{identifier|(}% \begin{bnf} -\nontermdef{character-literal}\br - \opt{encoding-prefix} \terminal{'} c-char-sequence \terminal{'} +\nontermdef{identifier}\br + identifier-start\br + identifier identifier-continue \end{bnf} \begin{bnf} -\nontermdef{encoding-prefix} \textnormal{one of}\br - \terminal{u8}\quad\terminal{u}\quad\terminal{U}\quad\terminal{L} +\nontermdef{identifier-start}\br + nondigit\br + \textnormal{an element of the translation character set with the Unicode property XID_Start} +\end{bnf} + +\begin{bnf} +\nontermdef{identifier-continue}\br + digit\br + nondigit\br + \textnormal{an element of the translation character set with the Unicode property XID_Continue} \end{bnf} \begin{bnf} -\nontermdef{c-char-sequence}\br - c-char\br - c-char-sequence c-char +\nontermdef{nondigit} \textnormal{one of}\br + \terminal{a b c d e f g h i j k l m}\br + \terminal{n o p q r s t u v w x y z}\br + \terminal{A B C D E F G H I J K L M}\br + \terminal{N O P Q R S T U V W X Y Z _} \end{bnf} \begin{bnf} -\nontermdef{c-char}\br - basic-c-char\br - escape-sequence\br - universal-character-name +\nontermdef{digit} \textnormal{one of}\br + \terminal{0 1 2 3 4 5 6 7 8 9} \end{bnf} +\pnum +\indextext{name!length of}% +\indextext{name}% +\begin{note} +The character properties XID_Start and XID_Continue are Derived Core Properties +as described by \UAX{44} of the Unicode Standard. +\begin{footnote} +On systems in which linkers cannot accept extended +characters, an encoding of the \grammarterm{universal-character-name} can be used in +forming valid external identifiers. For example, some otherwise unused +character or sequence of characters can be used to encode the +\tcode{\textbackslash u} in a \grammarterm{universal-character-name}. Extended +characters can produce a long external identifier, but \Cpp{} does not +place a translation limit on significant characters for external +identifiers. +\end{footnote} +\end{note} +The program is ill-formed +if an \grammarterm{identifier} does not conform to +Normalization Form C as specified in the Unicode Standard. +\begin{note} +Identifiers are case-sensitive. +\end{note} +\begin{note} +\ref{uaxid} compares the requirements of \UAX{31} of the Unicode Standard +with the \Cpp{} rules for identifiers. +\end{note} +\begin{note} +In translation phase 4, +\grammarterm{identifier} also includes +those \grammarterm{preprocessing-token}s\iref{lex.pptoken} +differentiated as keywords\iref{lex.key} +in the later translation phase 7\iref{lex.token}. +\end{note} + +\pnum +\indextext{\idxcode{_}|see{character, underscore}}% +\indextext{character!underscore!in identifier}% +\indextext{reserved identifier}% +In addition, some identifiers +appearing as a \grammarterm{token} or \grammarterm{preprocessing-token} +are reserved for use by \Cpp{} +implementations and shall +not be used otherwise; no diagnostic is required. +\begin{itemize} +\item +Each identifier that contains a double underscore +\tcode{\unun} +\indextext{character!underscore}% +or begins with an underscore followed by +an uppercase letter, +other than those specified in this document +(for example, \xname{cplusplus}\iref{cpp.predefined}), +\indextext{uppercase}% +is reserved to the implementation for any use. +\item +Each identifier that begins with an underscore is +\indextext{character!underscore}% +reserved to the implementation for use as a name in the global namespace.% +\indextext{namespace!global} +\end{itemize}% +\indextext{identifier|)} + +\rSec1[lex.tutokenize]{Translation unit tokenization} +\rSec2[lex.token]{Tokens} + +\indextext{token|(}% \begin{bnf} -\nontermdef{basic-c-char}\br - \textnormal{any member of the translation character set except the \unicode{0027}{apostrophe},}\br - \bnfindent\textnormal{\unicode{005c}{reverse solidus}, or new-line character} +\nontermdef{token}\br + identifier\br + keyword\br + literal\br + operator-or-punctuator \end{bnf} +\pnum +\indextext{\idxgram{token}}% +There are five kinds of tokens: identifiers, keywords, literals,% +\begin{footnote} +Literals include strings and character and numeric literals. +\end{footnote} +operators, and other separators. +\indextext{whitespace}% +Blanks, horizontal and vertical tabs, newlines, formfeeds, and comments +(collectively, ``whitespace''), are ignored except +as they serve to separate tokens. +\begin{note} +Whitespace can separate otherwise adjacent identifiers, keywords, numeric +literals, and alternative tokens containing alphabetic characters. +\end{note} +\indextext{token|)} + +\rSec2[lex.key]{Keywords} + \begin{bnf} -\nontermdef{escape-sequence}\br - simple-escape-sequence\br - numeric-escape-sequence\br - conditional-escape-sequence +\nontermdef{keyword}\br + \textnormal{any identifier listed in \tref{lex.key}}\br + \grammarterm{import-keyword}\br + \grammarterm{module-keyword}\br + \grammarterm{export-keyword} \end{bnf} +\pnum +\indextext{keyword|(}% +The identifiers shown in \tref{lex.key} are reserved for use +as keywords (that is, they are unconditionally treated as keywords in +phase 7) except in an \grammarterm{attribute-token}\iref{dcl.attr.grammar}. +\begin{note} +The \keyword{register} keyword is unused but +is reserved for future use. +\end{note} + +\begin{multicolfloattable}{Keywords}{lex.key} +{lllll} +\keyword{alignas} \\ +\keyword{alignof} \\ +\keyword{asm} \\ +\keyword{auto} \\ +\keyword{bool} \\ +\keyword{break} \\ +\keyword{case} \\ +\keyword{catch} \\ +\keyword{char} \\ +\keyword{char8_t} \\ +\keyword{char16_t} \\ +\keyword{char32_t} \\ +\keyword{class} \\ +\keyword{concept} \\ +\keyword{const} \\ +\keyword{consteval} \\ +\keyword{constexpr} \\ +\columnbreak +\keyword{constinit} \\ +\keyword{const_cast} \\ +\keyword{continue} \\ +\keyword{co_await} \\ +\keyword{co_return} \\ +\keyword{co_yield} \\ +\keyword{decltype} \\ +\keyword{default} \\ +\keyword{delete} \\ +\keyword{do} \\ +\keyword{double} \\ +\keyword{dynamic_cast} \\ +\keyword{else} \\ +\keyword{enum} \\ +\keyword{explicit} \\ +\keyword{export} \\ +\keyword{extern} \\ +\columnbreak +\keyword{false} \\ +\keyword{float} \\ +\keyword{for} \\ +\keyword{friend} \\ +\keyword{goto} \\ +\keyword{if} \\ +\keyword{inline} \\ +\keyword{int} \\ +\keyword{long} \\ +\keyword{mutable} \\ +\keyword{namespace} \\ +\keyword{new} \\ +\keyword{noexcept} \\ +\keyword{nullptr} \\ +\keyword{operator} \\ +\keyword{private} \\ +\keyword{protected} \\ +\columnbreak +\keyword{public} \\ +\keyword{register} \\ +\keyword{reinterpret_cast} \\ +\keyword{requires} \\ +\keyword{return} \\ +\keyword{short} \\ +\keyword{signed} \\ +\keyword{sizeof} \\ +\keyword{static} \\ +\keyword{static_assert} \\ +\keyword{static_cast} \\ +\keyword{struct} \\ +\keyword{switch} \\ +\keyword{template} \\ +\keyword{this} \\ +\keyword{thread_local} \\ +\keyword{throw} \\ +\columnbreak +\keyword{true} \\ +\keyword{try} \\ +\keyword{typedef} \\ +\keyword{typeid} \\ +\keyword{typename} \\ +\keyword{union} \\ +\keyword{unsigned} \\ +\keyword{using} \\ +\keyword{virtual} \\ +\keyword{void} \\ +\keyword{volatile} \\ +\keyword{wchar_t} \\ +\keyword{while} \\ +\end{multicolfloattable} + +\pnum +\indextext{\idxcode{import}}% +\indextext{\idxcode{final}}% +\indextext{\idxcode{module}}% +\indextext{\idxcode{override}}% +The identifiers in \tref{lex.name.special} have a special meaning when +appearing in a certain context. When referred to in the grammar, these identifiers +are used explicitly rather than using the \grammarterm{identifier} grammar production. +Unless otherwise specified, any ambiguity as to whether a given +\grammarterm{identifier} has a special meaning is resolved to interpret the +token as a regular \grammarterm{identifier}. + +\begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special} +{llll} +\keyword{final} \\ +\columnbreak +\keyword{import} \\ +\columnbreak +\keyword{module} \\ +\columnbreak +\keyword{override} \\ +\end{multicolfloattable} + +\pnum +\indextext{unit!translation}% +A translation unit shall not \tcode{\#define} or \tcode{\#undef} +names lexically identical +to keywords, +to the identifiers listed in \tref{lex.name.special}, or +to the \grammarterm{attribute-token}{s} described in~\ref{dcl.attr}, +except that the names \tcode{likely} and \tcode{unlikely} may be +defined as function-like macros~\iref{cpp.replace}. + +\pnum +Furthermore, the alternative representations shown in +\tref{lex.key.digraph} for certain operators and +punctuators\iref{lex.operators} are reserved and shall not be used +otherwise. + +\begin{floattable}{Alternative representations}{lex.key.digraph} +{llllll} +\topline +\keyword{and} & \keyword{and_eq} & \keyword{bitand} & \keyword{bitor} & \keyword{compl} & \keyword{not} \\ +\keyword{not_eq} & \keyword{or} & \keyword{or_eq} & \keyword{xor} & \keyword{xor_eq} & \\ +\end{floattable}% +\indextext{keyword|)}% + +\rSec2[lex.literal]{Literals}% +\indextext{literal|(} + +\rSec3[lex.literal.kinds]{Kinds of literals} + +\pnum +\indextext{constant}% +\indextext{literal!constant}% +There are several kinds of literals. +\begin{footnote} +The term ``literal'' generally designates, in this +document, those tokens that are called ``constants'' in C. +\end{footnote} + \begin{bnf} -\nontermdef{simple-escape-sequence}\br - \terminal{\textbackslash} simple-escape-sequence-char +\nontermdef{literal}\br + integer-literal\br + character-literal\br + floating-point-literal\br + string-literal\br + boolean-literal\br + pointer-literal\br + user-defined-literal \end{bnf} +\begin{note} +When appearing as an \grammarterm{expression}, +a literal has a type and a value category\iref{expr.prim.literal}. +\end{note} -\begin{bnf} -\nontermdef{simple-escape-sequence-char} \textnormal{one of}\br - \terminal{' " ? \textbackslash{} a b f n r t v} -\end{bnf} +\rSec3[lex.icon]{Integer literals} +\indextext{literal!integer}% \begin{bnf} -\nontermdef{numeric-escape-sequence}\br - octal-escape-sequence\br - hexadecimal-escape-sequence +\nontermdef{integer-literal}\br + binary-literal \opt{integer-suffix}\br + octal-literal \opt{integer-suffix}\br + decimal-literal \opt{integer-suffix}\br + hexadecimal-literal \opt{integer-suffix} \end{bnf} \begin{bnf} -\nontermdef{simple-octal-digit-sequence}\br - octal-digit\br - simple-octal-digit-sequence octal-digit +\nontermdef{binary-literal}\br + \terminal{0b} binary-digit\br + \terminal{0B} binary-digit\br + binary-literal \opt{\terminal{'}} binary-digit \end{bnf} \begin{bnf} -\nontermdef{octal-escape-sequence}\br - \terminal{\textbackslash} octal-digit\br - \terminal{\textbackslash} octal-digit octal-digit\br - \terminal{\textbackslash} octal-digit octal-digit octal-digit\br - \terminal{\textbackslash o\{} simple-octal-digit-sequence \terminal{\}}\br +\nontermdef{octal-literal}\br + \terminal{0}\br + octal-literal \opt{\terminal{'}} octal-digit \end{bnf} \begin{bnf} -\nontermdef{hexadecimal-escape-sequence}\br - \terminal{\textbackslash x} simple-hexadecimal-digit-sequence\br - \terminal{\textbackslash x\{} simple-hexadecimal-digit-sequence \terminal{\}} +\nontermdef{decimal-literal}\br + nonzero-digit\br + decimal-literal \opt{\terminal{'}} digit \end{bnf} \begin{bnf} -\nontermdef{conditional-escape-sequence}\br - \terminal{\textbackslash} conditional-escape-sequence-char +\nontermdef{hexadecimal-literal}\br + hexadecimal-prefix hexadecimal-digit-sequence \end{bnf} \begin{bnf} -\nontermdef{conditional-escape-sequence-char}\br - \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{N}, \terminal{o}, \terminal{u}, \terminal{U}, or \terminal{x}} +\nontermdef{binary-digit} \textnormal{one of}\br + \terminal{0 1} \end{bnf} -\pnum -\indextext{literal!character}% -\indextext{literal!\idxcode{char8_t}}% -\indextext{literal!\idxcode{char16_t}}% -\indextext{literal!\idxcode{char32_t}}% -\indextext{literal!type of character}% -\indextext{type!\idxcode{char8_t}}% -\indextext{type!\idxcode{char16_t}}% -\indextext{type!\idxcode{char32_t}}% -\indextext{wide-character}% -\indextext{type!\idxcode{wchar_t}}% -A \defnadj{multicharacter}{literal} is a \grammarterm{character-literal} -whose \grammarterm{c-char-sequence} consists of -more than one \grammarterm{c-char}. -A multicharacter literal shall not have an \grammarterm{encoding-prefix}. -If a multicharacter literal contains a \grammarterm{c-char} -that is not encodable as a single code unit in the ordinary literal encoding, -the program is ill-formed. -Multicharacter literals are conditionally-supported. - -\pnum -The kind of a \grammarterm{character-literal}, -its type, and its associated character encoding\iref{lex.charset} -are determined by -its \grammarterm{encoding-prefix} and its \grammarterm{c-char-sequence} -as defined by \tref{lex.ccon.literal}. - -\begin{floattable}{Character literals}{lex.ccon.literal} -{l|l|l|l|l} -\topline -\lhdr{Encoding} & \chdr{Kind} & \chdr{Type} & \chdr{Associated char-} & \rhdr{Example} \\ -\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{acter encoding} & \\ -\capsep -none & -\defnx{ordinary character literal}{literal!character!ordinary} & -\keyword{char} & -ordinary literal & -\tcode{'v'} \\ \cline{2-3}\cline{5-5} - & -multicharacter literal & -\keyword{int} & -encoding & -\tcode{'abcd'} \\ \hline -\tcode{L} & -\defnx{wide character literal}{literal!character!wide} & -\keyword{wchar_t} & -wide literal & -\tcode{L'w'} \\ - & & & encoding & \\ \hline -\tcode{u8} & -\defnx{UTF-8 character literal}{literal!character!UTF-8} & -\keyword{char8_t} & -UTF-8 & -\tcode{u8'x'} \\ \hline -\tcode{u} & -\defnx{UTF-16 character literal}{literal!character!UTF-16} & -\keyword{char16_t} & -UTF-16 & -\tcode{u'y'} \\ \hline -\tcode{U} & -\defnx{UTF-32 character literal}{literal!character!UTF-32} & -\keyword{char32_t} & -UTF-32 & -\tcode{U'z'} \\ -\end{floattable} - -\pnum -In translation phase 4, -the value of a \grammarterm{character-literal} is determined -using the range of representable values -of the \grammarterm{character-literal}'s type in translation phase 7. -A multicharacter literal has an -\impldef{value of non-encodable character literal or multicharacter literal} -value. -The value of any other kind of \grammarterm{character-literal} -is determined as follows: -\begin{itemize} -\item -A \grammarterm{character-literal} with -a \grammarterm{c-char-sequence} consisting of a single -\grammarterm{basic-c-char}, -\grammarterm{simple-escape-sequence}, or -\grammarterm{universal-character-name} -is the code unit value of the specified character -as encoded in the literal's associated character encoding. -If the specified character lacks -representation in the literal's associated character encoding or -if it cannot be encoded as a single code unit, -then the program is ill-formed. -\item -A \grammarterm{character-literal} with -a \grammarterm{c-char-sequence} consisting of -a single \grammarterm{numeric-escape-sequence} -has a value as follows: -\begin{itemize} -\item -Let $v$ be the integer value represented by -the octal number comprising -the sequence of \grammarterm{octal-digit}{s} in -an \grammarterm{octal-escape-sequence} or by -the hexadecimal number comprising -the sequence of \grammarterm{hexadecimal-digit}{s} in -a \grammarterm{hexadecimal-escape-sequence}. -\item -If $v$ does not exceed -the range of representable values of the \grammarterm{character-literal}'s type, -then the value is $v$. -\item -Otherwise, -if the \grammarterm{character-literal}'s \grammarterm{encoding-prefix} -is absent or \tcode{L}, and -$v$ does not exceed the range of representable values of the corresponding unsigned type for the underlying type of the \grammarterm{character-literal}'s type, -then the value is the unique value of the \grammarterm{character-literal}'s type \tcode{T} that is congruent to $v$ modulo $2^N$, where $N$ is the width of \tcode{T}. -\item -Otherwise, the program is ill-formed. -\end{itemize} -\item -A \grammarterm{character-literal} with -a \grammarterm{c-char-sequence} consisting of -a single \grammarterm{conditional-escape-sequence} -is conditionally-supported and -has an \impldef{value of \grammarterm{conditional-escape-sequence}} value. -\end{itemize} - -\pnum -\indextext{backslash character}% -\indextext{\idxcode{\textbackslash}|see{backslash character}}% -\indextext{escape character|see{backslash character}}% -The character specified by a \grammarterm{simple-escape-sequence} -is specified in \tref{lex.ccon.esc}. -\begin{note} -Using an escape sequence for a question mark -is supported for compatibility with \CppXIV{} and C. -\end{note} - -\begin{floattable}{Simple escape sequences}{lex.ccon.esc} -{lll} -\topline -\lhdrx{2}{character} & \rhdr{\grammarterm{simple-escape-sequence}} \\ \capsep -\ucode{000a} & \uname{line feed} & \tcode{\textbackslash n} \\ -\ucode{0009} & \uname{character tabulation} & \tcode{\textbackslash t} \\ -\ucode{000b} & \uname{line tabulation} & \tcode{\textbackslash v} \\ -\ucode{0008} & \uname{backspace} & \tcode{\textbackslash b} \\ -\ucode{000d} & \uname{carriage return} & \tcode{\textbackslash r} \\ -\ucode{000c} & \uname{form feed} & \tcode{\textbackslash f} \\ -\ucode{0007} & \uname{alert} & \tcode{\textbackslash a} \\ -\ucode{005c} & \uname{reverse solidus} & \tcode{\textbackslash\textbackslash} \\ -\ucode{003f} & \uname{question mark} & \tcode{\textbackslash ?} \\ -\ucode{0027} & \uname{apostrophe} & \tcode{\textbackslash '} \\ -\ucode{0022} & \uname{quotation mark} & \tcode{\textbackslash "} \\ -\end{floattable} - -\rSec2[lex.fcon]{Floating-point literals} - -\indextext{literal!floating-point}% \begin{bnf} -\nontermdef{floating-point-literal}\br - decimal-floating-point-literal\br - hexadecimal-floating-point-literal +\nontermdef{octal-digit} \textnormal{one of}\br + \terminal{0 1 2 3 4 5 6 7} \end{bnf} \begin{bnf} -\nontermdef{decimal-floating-point-literal}\br - fractional-constant \opt{exponent-part} \opt{floating-point-suffix}\br - digit-sequence exponent-part \opt{floating-point-suffix} +\nontermdef{nonzero-digit} \textnormal{one of}\br + \terminal{1 2 3 4 5 6 7 8 9} \end{bnf} \begin{bnf} -\nontermdef{hexadecimal-floating-point-literal}\br - hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part \opt{floating-point-suffix}\br - hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part \opt{floating-point-suffix} +\nontermdef{hexadecimal-prefix} \textnormal{one of}\br + \terminal{0x 0X} \end{bnf} \begin{bnf} -\nontermdef{fractional-constant}\br - \opt{digit-sequence} \terminal{.} digit-sequence\br - digit-sequence \terminal{.} +\nontermdef{hexadecimal-digit-sequence}\br + hexadecimal-digit\br + hexadecimal-digit-sequence \opt{\terminal{'}} hexadecimal-digit \end{bnf} \begin{bnf} -\nontermdef{hexadecimal-fractional-constant}\br - \opt{hexadecimal-digit-sequence} \terminal{.} hexadecimal-digit-sequence\br - hexadecimal-digit-sequence \terminal{.} +\nontermdef{hexadecimal-digit} \textnormal{one of}\br + \terminal{0 1 2 3 4 5 6 7 8 9}\br + \terminal{a b c d e f}\br + \terminal{A B C D E F} \end{bnf} \begin{bnf} -\nontermdef{exponent-part}\br - \terminal{e} \opt{sign} digit-sequence\br - \terminal{E} \opt{sign} digit-sequence +\nontermdef{integer-suffix}\br + unsigned-suffix \opt{long-suffix} \br + unsigned-suffix \opt{long-long-suffix} \br + unsigned-suffix \opt{size-suffix} \br + long-suffix \opt{unsigned-suffix} \br + long-long-suffix \opt{unsigned-suffix} \br + size-suffix \opt{unsigned-suffix} \end{bnf} \begin{bnf} -\nontermdef{binary-exponent-part}\br - \terminal{p} \opt{sign} digit-sequence\br - \terminal{P} \opt{sign} digit-sequence +\nontermdef{unsigned-suffix} \textnormal{one of}\br + \terminal{u U} \end{bnf} \begin{bnf} -\nontermdef{sign} \textnormal{one of}\br - \terminal{+ -} +\nontermdef{long-suffix} \textnormal{one of}\br + \terminal{l L} \end{bnf} \begin{bnf} -\nontermdef{digit-sequence}\br - digit\br - digit-sequence \opt{\terminal{'}} digit +\nontermdef{long-long-suffix} \textnormal{one of}\br + \terminal{ll LL} \end{bnf} \begin{bnf} -\nontermdef{floating-point-suffix} \textnormal{one of}\br - \terminal{f l f16 f32 f64 f128 bf16 F L F16 F32 F64 F128 BF16} +\nontermdef{size-suffix} \textnormal{one of}\br + \terminal{z Z} \end{bnf} \pnum -\indextext{literal!type of floating-point}% -\indextext{literal!\idxcode{float}}% -\indextext{suffix!\idxcode{F}}% -\indextext{suffix!\idxcode{f}}% -\indextext{suffix!\idxcode{L}}% -\indextext{suffix!\idxcode{l}}% -\indextext{literal!\idxcode{long double}}% -The type of -a \grammarterm{floating-point-literal}\iref{basic.fundamental,basic.extended.fp} -is determined by -its \grammarterm{floating-point-suffix} as specified in \tref{lex.fcon.type}. +\indextext{literal!\idxcode{unsigned}}% +\indextext{literal!\idxcode{long}}% +\indextext{literal!base of integer}% +In an \grammarterm{integer-literal}, +the sequence of +\grammarterm{binary-digit}s, +\grammarterm{octal-digit}s, +\grammarterm{digit}s, or +\grammarterm{hexadecimal-digit}s +is interpreted as a base $N$ integer as shown in table \tref{lex.icon.base}; +the lexically first digit of the sequence of digits is the most significant. \begin{note} -The floating-point suffixes -\tcode{f16}, \tcode{f32}, \tcode{f64}, \tcode{f128}, \tcode{bf16}, -\tcode{F16}, \tcode{F32}, \tcode{F64}, \tcode{F128}, and \tcode{BF16} -are conditionally-supported. See \ref{basic.extended.fp}. +The prefix and any optional separating single quotes are ignored +when determining the value. \end{note} + \begin{simpletypetable} -{Types of \grammarterm{floating-point-literal}{s}} -{lex.fcon.type} -{ll} +{Base of \grammarterm{integer-literal}{s}} +{lex.icon.base} +{lr} \topline -\lhdr{\grammarterm{floating-point-suffix}} & \rhdr{type} \\ \capsep -none & \keyword{double} \\ -\tcode{f} or \tcode{F} & \keyword {float} \\ -\tcode{l} or \tcode{L} & \keyword{long} \keyword{double} \\ -\tcode{f16} or \tcode{F16} & \tcode{std::float16_t} \\ -\tcode{f32} or \tcode{F32} & \tcode{std::float32_t} \\ -\tcode{f64} or \tcode{F64} & \tcode{std::float64_t} \\ -\tcode{f128} or \tcode{F128} & \tcode{std::float128_t} \\ -\tcode{bf16} or \tcode{BF16} & \tcode{std::bfloat16_t} \\ +\lhdr{Kind of \grammarterm{integer-literal}} & \rhdr{base $N$} \\ \capsep +\grammarterm{binary-literal} & 2 \\ +\grammarterm{octal-literal} & 8 \\ +\grammarterm{decimal-literal} & 10 \\ +\grammarterm{hexadecimal-literal} & 16 \\ \end{simpletypetable} \pnum -\indextext{literal!floating-point}% -The \defn{significand} of a \grammarterm{floating-point-literal} -is the \grammarterm{fractional-constant} or \grammarterm{digit-sequence} -of a \grammarterm{decimal-floating-point-literal} -or the \grammarterm{hexadecimal-fractional-constant} -or \grammarterm{hexadecimal-digit-sequence} -of a \grammarterm{hexadecimal-floating-point-literal}. -In the significand, -the sequence of \grammarterm{digit}s or \grammarterm{hexadecimal-digit}s -and optional period are interpreted as a base $N$ real number $s$, -where $N$ is 10 for a \grammarterm{decimal-floating-point-literal} and -16 for a \grammarterm{hexadecimal-floating-point-literal}. -\begin{note} -Any optional separating single quotes are ignored when determining the value. -\end{note} -If an \grammarterm{exponent-part} or \grammarterm{binary-exponent-part} -is present, -the exponent $e$ of the \grammarterm{floating-point-literal} -is the result of interpreting -the sequence of an optional \grammarterm{sign} and the \grammarterm{digit}s -as a base 10 integer. -Otherwise, the exponent $e$ is 0. -The scaled value of the literal is -$s \times 10^e$ for a \grammarterm{decimal-floating-point-literal} and -$s \times 2^e$ for a \grammarterm{hexadecimal-floating-point-literal}. +The \grammarterm{hexadecimal-digit}s +\tcode{a} through \tcode{f} and \tcode{A} through \tcode{F} +have decimal values ten through fifteen. \begin{example} -The \grammarterm{floating-point-literal}{s} -\tcode{49.625} and \tcode{0xC.68p+2} have the same value. -The \grammarterm{floating-point-literal}{s} -\tcode{1.602'176'565e-19} and \tcode{1.602176565e-19} -have the same value. +The number twelve can be written \tcode{12}, \tcode{014}, +\tcode{0XC}, or \tcode{0b1100}. The \grammarterm{integer-literal}s \tcode{1048576}, +\tcode{1'048'576}, \tcode{0X100000}, \tcode{0x10'0000}, and +\tcode{0'004'000'000} all have the same value. \end{example} \pnum -If the scaled value is not in the range of representable -values for its type, the program is ill-formed. -Otherwise, the value of a \grammarterm{floating-point-literal} -is the scaled value if representable, -else the larger or smaller representable value nearest the scaled value, -chosen in an \impldef{choice of larger or smaller value of -\grammarterm{floating-point-literal}} manner. +\indextext{literal!\idxcode{long}}% +\indextext{literal!\idxcode{unsigned}}% +\indextext{literal!integer}% +\indextext{literal!type of integer}% +\indextext{suffix!\idxcode{L}}% +\indextext{suffix!\idxcode{U}}% +\indextext{suffix!\idxcode{l}}% +\indextext{suffix!\idxcode{u}}% +The type of an \grammarterm{integer-literal} is +the first type in the list in \tref{lex.icon.type} +corresponding to its optional \grammarterm{integer-suffix} +in which its value can be represented. -\rSec2[lex.string]{String literals} +\begin{floattable}{Types of \grammarterm{integer-literal}s}{lex.icon.type}{l|l|l} +\topline +\lhdr{\grammarterm{integer-suffix}} & \chdr{\grammarterm{decimal-literal}} & \rhdr{\grammarterm{integer-literal} other than \grammarterm{decimal-literal}} \\ \capsep +none & + \tcode{int} & + \tcode{int}\\ + & + \tcode{long int} & + \tcode{unsigned int}\\ + & + \tcode{long long int} & + \tcode{long int}\\ + & + & + \tcode{unsigned long int}\\ + & + & + \tcode{long long int}\\ + & + & + \tcode{unsigned long long int}\\\hline +\tcode{u} or \tcode{U} & + \tcode{unsigned int} & + \tcode{unsigned int}\\ + & + \tcode{unsigned long int} & + \tcode{unsigned long int}\\ + & + \tcode{unsigned long long int} & + \tcode{unsigned long long int}\\\hline +\tcode{l} or \tcode{L} & + \tcode{long int} & + \tcode{long int}\\ + & + \tcode{long long int} & + \tcode{unsigned long int}\\ + & + & + \tcode{long long int}\\ + & + & + \tcode{unsigned long long int}\\\hline +Both \tcode{u} or \tcode{U} & + \tcode{unsigned long int} & + \tcode{unsigned long int}\\ +and \tcode{l} or \tcode{L} & + \tcode{unsigned long long int} & + \tcode{unsigned long long int}\\\hline +\tcode{ll} or \tcode{LL} & + \tcode{long long int} & + \tcode{long long int}\\ + & + & + \tcode{unsigned long long int}\\\hline +Both \tcode{u} or \tcode{U} & + \tcode{unsigned long long int} & + \tcode{unsigned long long int}\\ +and \tcode{ll} or \tcode{LL} & + & + \\\hline +\tcode{z} or \tcode{Z} & + the signed integer type corresponding & + the signed integer type \\ + & + \qquad to \tcode{std::size_t}\iref{support.types.layout} & + \qquad corresponding to \tcode{std::size_t} \\ + & + & + \tcode{std::size_t}\\\hline +Both \tcode{u} or \tcode{U} & + \tcode{std::size_t} & + \tcode{std::size_t} \\ +and \tcode{z} or \tcode{Z} & + & + \\ +\end{floattable} -\indextext{literal!string}% +\pnum +Except for \grammarterm{integer-literal}{s} containing +a \grammarterm{size-suffix}, +if the value of an \grammarterm{integer-literal} +cannot be represented by any type in its list and +an extended integer type\iref{basic.fundamental} can represent its value, +it may have that extended integer type. +If all of the types in the list for the \grammarterm{integer-literal} +are signed, +the extended integer type is signed. +If all of the types in the list for the \grammarterm{integer-literal} +are unsigned, +the extended integer type is unsigned. +If the list contains both signed and unsigned types, +the extended integer type may be signed or unsigned. +If an \grammarterm{integer-literal} +cannot be represented by any of the allowed types, +the program is ill-formed. +\begin{note} +An \grammarterm{integer-literal} with a \tcode{z} or \tcode{Z} suffix +is ill-formed if it cannot be represented by \tcode{std::size_t}. +\end{note} + +\rSec3[lex.fcon]{Floating-point literals} + +\indextext{literal!floating-point}% \begin{bnf} -\nontermdef{string-literal}\br - \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br - \opt{encoding-prefix} \terminal{R} raw-string +\nontermdef{floating-point-literal}\br + decimal-floating-point-literal\br + hexadecimal-floating-point-literal \end{bnf} \begin{bnf} -\nontermdef{s-char-sequence}\br - s-char\br - s-char-sequence s-char +\nontermdef{decimal-floating-point-literal}\br + fractional-constant \opt{exponent-part} \opt{floating-point-suffix}\br + digit-sequence exponent-part \opt{floating-point-suffix} \end{bnf} \begin{bnf} -\nontermdef{s-char}\br - basic-s-char\br - escape-sequence\br - universal-character-name +\nontermdef{hexadecimal-floating-point-literal}\br + hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part \opt{floating-point-suffix}\br + hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part \opt{floating-point-suffix} \end{bnf} \begin{bnf} -\nontermdef{basic-s-char}\br - \textnormal{any member of the translation character set except the \unicode{0022}{quotation mark},}\br - \bnfindent\textnormal{\unicode{005c}{reverse solidus}, or new-line character} +\nontermdef{fractional-constant}\br + \opt{digit-sequence} \terminal{.} digit-sequence\br + digit-sequence \terminal{.} +\end{bnf} + +\begin{bnf} +\nontermdef{hexadecimal-fractional-constant}\br + \opt{hexadecimal-digit-sequence} \terminal{.} hexadecimal-digit-sequence\br + hexadecimal-digit-sequence \terminal{.} \end{bnf} \begin{bnf} -\nontermdef{raw-string}\br - \terminal{"} \opt{d-char-sequence} \terminal{(} \opt{r-char-sequence} \terminal{)} \opt{d-char-sequence} \terminal{"} +\nontermdef{exponent-part}\br + \terminal{e} \opt{sign} digit-sequence\br + \terminal{E} \opt{sign} digit-sequence \end{bnf} \begin{bnf} -\nontermdef{r-char-sequence}\br - r-char\br - r-char-sequence r-char +\nontermdef{binary-exponent-part}\br + \terminal{p} \opt{sign} digit-sequence\br + \terminal{P} \opt{sign} digit-sequence \end{bnf} \begin{bnf} -\nontermdef{r-char}\br - \textnormal{any member of the translation character set, except a \unicode{0029}{right parenthesis} followed by}\br - \bnfindent\textnormal{the initial \grammarterm{d-char-sequence} (which may be empty) followed by a \unicode{0022}{quotation mark}} +\nontermdef{sign} \textnormal{one of}\br + \terminal{+ -} \end{bnf} \begin{bnf} -\nontermdef{d-char-sequence}\br - d-char\br - d-char-sequence d-char +\nontermdef{digit-sequence}\br + digit\br + digit-sequence \opt{\terminal{'}} digit \end{bnf} \begin{bnf} -\nontermdef{d-char}\br - \textnormal{any member of the basic character set except:}\br - \bnfindent\textnormal{\unicode{0020}{space}, \unicode{0028}{left parenthesis}, \unicode{0029}{right parenthesis}, \unicode{005c}{reverse solidus},}\br - \bnfindent\textnormal{\unicode{0009}{character tabulation}, \unicode{000b}{line tabulation}, \unicode{000c}{form feed}, and new-line} +\nontermdef{floating-point-suffix} \textnormal{one of}\br + \terminal{f l f16 f32 f64 f128 bf16 F L F16 F32 F64 F128 BF16} \end{bnf} \pnum -\indextext{literal!string}% -\indextext{character string}% -\indextext{string!type of}% -\indextext{type!\idxcode{wchar_t}}% -\indextext{prefix!\idxcode{L}}% -\indextext{literal!string!\idxcode{char16_t}}% -\indextext{type!\idxcode{char16_t}}% -\indextext{literal!string!\idxcode{char32_t}}% -\indextext{type!\idxcode{char32_t}}% -The kind of a \grammarterm{string-literal}, -its type, and -its associated character encoding\iref{lex.charset} -are determined by its encoding prefix and sequence of -\grammarterm{s-char}s or \grammarterm{r-char}s -as defined by \tref{lex.string.literal} -where $n$ is the number of encoded code units as described below. - -\begin{floattable}{String literals}{lex.string.literal} -{llp{2.6cm}p{2.3cm}p{4.7cm}} -\topline -\lhdr{Enco-} & \chdr{Kind} & \chdr{Type} & \chdr{Associated} & \rhdr{Examples} \\ -\lhdr{ding} & \chdr{} & \chdr{} & \chdr{character} & \rhdr{} \\ -\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{encoding} & \rhdr{} \\ -\capsep -none & -\defnx{ordinary string literal}{literal!string!ordinary} & -array of $n$\newline \tcode{\keyword{const} \keyword{char}} & -ordinary literal encoding & -\tcode{"ordinary string"}\newline -\tcode{R"(ordinary raw string)"} \\ -\tcode{L} & -\defnx{wide string literal}{literal!string!wide} & -array of $n$\newline \tcode{\keyword{const} \keyword{wchar_t}} & -wide literal\newline encoding & -\tcode{L"wide string"}\newline -\tcode{LR"w(wide raw string)w"} \\ -\tcode{u8} & -\defnx{UTF-8 string literal}{literal!string!UTF-8} & -array of $n$\newline \tcode{\keyword{const} \keyword{char8_t}} & -UTF-8 & -\tcode{u8"UTF-8 string"}\newline -\tcode{u8R"x(UTF-8 raw string)x"} \\ -\tcode{u} & -\defnx{UTF-16 string literal}{literal!string!UTF-16} & -array of $n$\newline \tcode{\keyword{const} \keyword{char16_t}} & -UTF-16 & -\tcode{u"UTF-16 string"}\newline -\tcode{uR"y(UTF-16 raw string)y"} \\ -\tcode{U} & -\defnx{UTF-32 string literal}{literal!string!UTF-32} & -array of $n$\newline \tcode{\keyword{const} \keyword{char32_t}} & -UTF-32 & -\tcode{U"UTF-32 string"}\newline -\tcode{UR"z(UTF-32 raw string)z"} \\ -\end{floattable} - -\pnum -\indextext{literal!string!raw}% -A \grammarterm{string-literal} that has an \tcode{R} -\indextext{prefix!\idxcode{R}}% -in the prefix is a \defn{raw string literal}. The -\grammarterm{d-char-sequence} serves as a delimiter. The terminating -\grammarterm{d-char-sequence} of a \grammarterm{raw-string} is the same sequence of -characters as the initial \grammarterm{d-char-sequence}. A \grammarterm{d-char-sequence} -shall consist of at most 16 characters. - -\pnum -\begin{note} -The characters \tcode{'('} and \tcode{')'} can appear in a -\grammarterm{raw-string}. Thus, \tcode{R"delimiter((a|b))delimiter"} is equivalent to -\tcode{"(a|b)"}. -\end{note} - -\pnum -\begin{note} -A source-file new-line in a raw string literal results in a new-line in the -resulting execution string literal. Assuming no -whitespace at the beginning of lines in the following example, the assert will succeed: -\begin{codeblock} -const char* p = R"(a\ -b -c)"; -assert(std::strcmp(p, "a\\\nb\nc") == 0); -\end{codeblock} -\end{note} - -\pnum -\begin{example} -The raw string -\begin{codeblock} -R"a( -)\ -a" -)a" -\end{codeblock} -is equivalent to \tcode{"\textbackslash n)\textbackslash \textbackslash \textbackslash na\textbackslash"\textbackslash n"}. The raw string -\begin{codeblock} -R"(x = "\"y\"")" -\end{codeblock} -is equivalent to \tcode{"x = \textbackslash "\textbackslash\textbackslash\textbackslash "y\textbackslash\textbackslash\textbackslash "\textbackslash ""}. -\end{example} - -\pnum -\indextext{literal!narrow-character}% -Ordinary string literals and UTF-8 string literals are -also referred to as \defnx{narrow string literals}{literal!string!narrow}. - -\pnum -\indextext{concatenation!string}% -The \grammarterm{string-literal}{s} in -any sequence of adjacent \grammarterm{string-literal}{s} -shall have at most one unique \grammarterm{encoding-prefix} among them. -The common \grammarterm{encoding-prefix} of the sequence is -that \grammarterm{encoding-prefix}, if any. +\indextext{literal!type of floating-point}% +\indextext{literal!\idxcode{float}}% +\indextext{suffix!\idxcode{F}}% +\indextext{suffix!\idxcode{f}}% +\indextext{suffix!\idxcode{L}}% +\indextext{suffix!\idxcode{l}}% +\indextext{literal!\idxcode{long double}}% +The type of +a \grammarterm{floating-point-literal}\iref{basic.fundamental,basic.extended.fp} +is determined by +its \grammarterm{floating-point-suffix} as specified in \tref{lex.fcon.type}. \begin{note} -A \grammarterm{string-literal}'s rawness has -no effect on the determination of the common \grammarterm{encoding-prefix}. +The floating-point suffixes +\tcode{f16}, \tcode{f32}, \tcode{f64}, \tcode{f128}, \tcode{bf16}, +\tcode{F16}, \tcode{F32}, \tcode{F64}, \tcode{F128}, and \tcode{BF16} +are conditionally-supported. See \ref{basic.extended.fp}. \end{note} - -\pnum -In translation phase 6\iref{lex.phases}, -adjacent \grammarterm{string-literal}s are concatenated. -The lexical structure and grouping of -the contents of the individual \grammarterm{string-literal}s is retained. -\begin{example} -\begin{codeblock} -"\xA" "B" -\end{codeblock} -represents -the code unit \tcode{'\textbackslash xA'} and the character \tcode{'B'} -after concatenation -(and not the single code unit \tcode{'\textbackslash xAB'}). -Similarly, -\begin{codeblock} -R"(\u00)" "41" -\end{codeblock} -represents six characters, -starting with a backslash and ending with the digit \tcode{1} -(and not the single character \tcode{'A'} -specified by a \grammarterm{universal-character-name}). - -\tref{lex.string.concat} has some examples of valid concatenations. -\end{example} - -\begin{floattable}{String literal concatenations}{lex.string.concat} -{lll|lll|lll} +\begin{simpletypetable} +{Types of \grammarterm{floating-point-literal}{s}} +{lex.fcon.type} +{ll} \topline -\multicolumn{2}{|c}{Source} & -Means & -\multicolumn{2}{c}{Source} & -Means & -\multicolumn{2}{c}{Source} & -Means \\ -\tcode{u"a"} & \tcode{u"b"} & \tcode{u"ab"} & -\tcode{U"a"} & \tcode{U"b"} & \tcode{U"ab"} & -\tcode{L"a"} & \tcode{L"b"} & \tcode{L"ab"} \\ -\tcode{u"a"} & \tcode{"b"} & \tcode{u"ab"} & -\tcode{U"a"} & \tcode{"b"} & \tcode{U"ab"} & -\tcode{L"a"} & \tcode{"b"} & \tcode{L"ab"} \\ -\tcode{"a"} & \tcode{u"b"} & \tcode{u"ab"} & -\tcode{"a"} & \tcode{U"b"} & \tcode{U"ab"} & -\tcode{"a"} & \tcode{L"b"} & \tcode{L"ab"} \\ -\end{floattable} - -\pnum -Evaluating a \grammarterm{string-literal} results in a string literal object -with static storage duration\iref{basic.stc}. -\begin{note} -String literal objects are potentially non-unique\iref{intro.object}. -Whether successive evaluations of a -\grammarterm{string-literal} yield the same or a different object is -unspecified. -\end{note} -\begin{note} -\indextext{literal!string!undefined change to}% -The effect of attempting to modify a string literal object is undefined. -\end{note} - -\pnum -\indextext{\idxcode{0}!string terminator}% -\indextext{\idxcode{0}!null character|see {character, null}}% -String literal objects are initialized with -the sequence of code unit values -corresponding to the \grammarterm{string-literal}'s sequence of -\grammarterm{s-char}s (originally from non-raw string literals) and -\grammarterm{r-char}s (originally from raw string literals), -plus a terminating \unicode{0000}{null} character, -in order as follows: -\begin{itemize} -\item -The sequence of characters denoted by each contiguous sequence of -\grammarterm{basic-s-char}s, -\grammarterm{r-char}s, -\grammarterm{simple-escape-sequence}s\iref{lex.ccon}, and -\grammarterm{universal-character-name}s\iref{lex.charset} -is encoded to a code unit sequence -using the \grammarterm{string-literal}'s associated character encoding. -If a character lacks representation in the associated character encoding, -then the program is ill-formed. -\begin{note} -No character lacks representation in any Unicode encoding form. -\end{note} -When encoding a stateful character encoding, -implementations should encode the first such sequence -beginning with the initial encoding state and -encode subsequent sequences -beginning with the final encoding state of the prior sequence. +\lhdr{\grammarterm{floating-point-suffix}} & \rhdr{type} \\ \capsep +none & \keyword{double} \\ +\tcode{f} or \tcode{F} & \keyword {float} \\ +\tcode{l} or \tcode{L} & \keyword{long} \keyword{double} \\ +\tcode{f16} or \tcode{F16} & \tcode{std::float16_t} \\ +\tcode{f32} or \tcode{F32} & \tcode{std::float32_t} \\ +\tcode{f64} or \tcode{F64} & \tcode{std::float64_t} \\ +\tcode{f128} or \tcode{F128} & \tcode{std::float128_t} \\ +\tcode{bf16} or \tcode{BF16} & \tcode{std::bfloat16_t} \\ +\end{simpletypetable} + +\pnum +\indextext{literal!floating-point}% +The \defn{significand} of a \grammarterm{floating-point-literal} +is the \grammarterm{fractional-constant} or \grammarterm{digit-sequence} +of a \grammarterm{decimal-floating-point-literal} +or the \grammarterm{hexadecimal-fractional-constant} +or \grammarterm{hexadecimal-digit-sequence} +of a \grammarterm{hexadecimal-floating-point-literal}. +In the significand, +the sequence of \grammarterm{digit}s or \grammarterm{hexadecimal-digit}s +and optional period are interpreted as a base $N$ real number $s$, +where $N$ is 10 for a \grammarterm{decimal-floating-point-literal} and +16 for a \grammarterm{hexadecimal-floating-point-literal}. \begin{note} -The encoded code unit sequence can differ from -the sequence of code units that would be obtained by -encoding each character independently. +Any optional separating single quotes are ignored when determining the value. \end{note} -\item -Each \grammarterm{numeric-escape-sequence}\iref{lex.ccon} -contributes a single code unit with a value as follows: -\begin{itemize} -\item -Let $v$ be the integer value represented by -the octal number comprising -the sequence of \grammarterm{octal-digit}{s} in -an \grammarterm{octal-escape-sequence} or by -the hexadecimal number comprising -the sequence of \grammarterm{hexadecimal-digit}{s} in -a \grammarterm{hexadecimal-escape-sequence}. -\item -If $v$ does not exceed the range of representable values of -the \grammarterm{string-literal}'s array element type, -then the value is $v$. -\item -Otherwise, -if the \grammarterm{string-literal}'s \grammarterm{encoding-prefix} -is absent or \tcode{L}, and -$v$ does not exceed the range of representable values of -the corresponding unsigned type for the underlying type of -the \grammarterm{string-literal}'s array element type, -then the value is the unique value of -the \grammarterm{string-literal}'s array element type \tcode{T} -that is congruent to $v$ modulo $2^N$, where $N$ is the width of \tcode{T}. -\item -Otherwise, the program is ill-formed. -\end{itemize} -When encoding a stateful character encoding, -these sequences should have no effect on encoding state. -\item -Each \grammarterm{conditional-escape-sequence}\iref{lex.ccon} -contributes an -\impldef{code unit sequence for \grammarterm{conditional-escape-sequence}} -code unit sequence. -When encoding a stateful character encoding, -it is -\impldef{effect of \grammarterm{conditional-escape-sequence} on encoding state} -what effect these sequences have on encoding state. -\end{itemize} +If an \grammarterm{exponent-part} or \grammarterm{binary-exponent-part} +is present, +the exponent $e$ of the \grammarterm{floating-point-literal} +is the result of interpreting +the sequence of an optional \grammarterm{sign} and the \grammarterm{digit}s +as a base 10 integer. +Otherwise, the exponent $e$ is 0. +The scaled value of the literal is +$s \times 10^e$ for a \grammarterm{decimal-floating-point-literal} and +$s \times 2^e$ for a \grammarterm{hexadecimal-floating-point-literal}. +\begin{example} +The \grammarterm{floating-point-literal}{s} +\tcode{49.625} and \tcode{0xC.68p+2} have the same value. +The \grammarterm{floating-point-literal}{s} +\tcode{1.602'176'565e-19} and \tcode{1.602176565e-19} +have the same value. +\end{example} + +\pnum +If the scaled value is not in the range of representable +values for its type, the program is ill-formed. +Otherwise, the value of a \grammarterm{floating-point-literal} +is the scaled value if representable, +else the larger or smaller representable value nearest the scaled value, +chosen in an \impldef{choice of larger or smaller value of +\grammarterm{floating-point-literal}} manner. -\rSec2[lex.string.uneval]{Unevaluated strings} +\rSec3[lex.string.uneval]{Unevaluated strings} \begin{bnf} \nontermdef{unevaluated-string}\br @@ -2068,7 +2083,7 @@ An \grammarterm{unevaluated-string} is never evaluated and its interpretation depends on the context in which it appears. -\rSec2[lex.bool]{Boolean literals} +\rSec3[lex.bool]{Boolean literals} \indextext{literal!boolean}% \begin{bnf} @@ -2082,7 +2097,7 @@ The Boolean literals are the keywords \tcode{false} and \tcode{true}. Such literals have type \tcode{bool}. -\rSec2[lex.nullptr]{Pointer literals} +\rSec3[lex.nullptr]{Pointer literals} \indextext{literal!pointer}% \begin{bnf} @@ -2100,7 +2115,7 @@ and~\ref{conv.mem}. \end{note} -\rSec2[lex.ext]{User-defined literals} +\rSec3[lex.ext]{User-defined literals} \indextext{literal!user-defined}% \begin{bnf} @@ -2280,4 +2295,517 @@ \end{codeblock} \end{example} \indextext{literal|)}% + +\rSec1[basic.link]{Names and linkage}% +\indextext{linkage|(} + +\pnum +\indextext{type}% +\indextext{object}% +\indextext{storage class}% +\indextext{scope}% +\indextext{linkage}% +A \defn{name} is an \grammarterm{identifier}\iref{lex.name}, +\grammarterm{operator-function-id}\iref{over.oper}, +\grammarterm{literal-operator-id}\iref{over.literal}, or +\grammarterm{conversion-function-id}\iref{class.conv.fct}. + +\pnum +Two names are \defnx{the same}{name!same} if +\begin{itemize} +\item they are \grammarterm{identifier}{s} composed of the same character sequence, or +\item they are \grammarterm{operator-function-id}{s} formed with the same operator, or +\item they are \grammarterm{literal-operator-id}{s} formed with the same +literal suffix identifier, or +\item they are \grammarterm{conversion-function-id}{s} formed with +equivalent\iref{temp.over.link} types. +\end{itemize} + +\pnum +Every name is introduced by a \defn{declaration}, which is a +\begin{itemize} +\item +\grammarterm{name-declaration}, +\grammarterm{block-declaration}, or +\grammarterm{member-declaration}\iref{dcl.pre,class.mem}, +\item +\grammarterm{init-capture}\iref{expr.prim.lambda.capture}, +\item +\grammarterm{condition} with a \grammarterm{declarator}\iref{stmt.pre}, +\item +\grammarterm{exception-declaration}\iref{except.pre}, +\item +\grammarterm{elaborated-type-specifier} +that introduces a name\iref{dcl.type.elab}, +\item +\grammarterm{init-declarator}\iref{dcl.decl}, +\item +\grammarterm{parameter-declaration}\iref{dcl.fct}, +\item +\grammarterm{identifier} +in a structured binding declaration\iref{dcl.struct.bind}, +\item +\grammarterm{enum-specifier} or +\grammarterm{enumerator-definition}\iref{dcl.enum}, +\item +\grammarterm{using-declarator}\iref{namespace.udecl}, +\item +\grammarterm{class-specifier}\iref{class.pre}, +\item +implicit declaration of an injected-class-name\iref{class.pre}, +\item +\grammarterm{member-declarator}\iref{class.mem}, or +\item +\grammarterm{type-parameter}\iref{temp.param}. +\end{itemize} +\begin{note} +The interpretation of a \grammarterm{for-range-declaration} produces +one or more of the above\iref{stmt.ranged}. +\end{note} + +\pnum +An \defn{entity} is a value, object, reference, structured binding, function, +enumerator, type, class member, bit-field, template, template specialization, +namespace, or pack. An entity $E$ is denoted by the name (if any) that is +introduced by a declaration of $E$ or by a \grammarterm{typedef-name} +introduced by a declaration specifying $E$. + +\pnum +Some names denote types or templates. In general, whenever a name is +encountered it is necessary to determine whether that name denotes one of these +entities before continuing to parse the program that contains it. The process +that determines this is called +\defnx{name lookup}{lookup!name}\iref{basic.lookup}. + +\pnum +A \defn{variable} is introduced by the +declaration of +a reference other than a non-static data member or of +an object. The variable's name, if any, denotes the reference or object. + +\pnum +A name can have +\defnadj{external}{linkage}, +\defnadj{module}{linkage}, +\defnadj{internal}{linkage}, or +\defnadj{no}{linkage}, +as determined by the rules below. +\begin{note} +All declarations of an entity with a name with internal linkage +appear in the same translation unit. +All declarations of an entity with module linkage +are attached to the same module. +\end{note} + +\pnum +\indextext{linkage!\idxcode{static} and}% +\indextext{\idxcode{static}!linkage of}% +\indextext{linkage!\idxcode{const} and}% +\indextext{\idxcode{const}!linkage of}% +\indextext{linkage!\idxcode{inline} and}% +\indextext{\idxcode{inline}!linkage of}% +The name of an entity +that belongs to a namespace scope\iref{basic.scope.namespace} +has internal linkage if it is the name of +\begin{itemize} +\item + a variable, variable template, function, or function template that is + explicitly declared \keyword{static}; or +\item + a non-template variable of non-volatile const-qualified type, unless + \begin{itemize} + \item it is declared in the purview of a module interface unit + (outside the \grammarterm{private-module-fragment}, if any) or + module partition, or + \item it is explicitly declared \keyword{extern}, or + \item it is inline, or + \item it was previously declared and the prior declaration did + not have internal linkage; or + \end{itemize} +\item + a data member of an anonymous union. +\end{itemize} +\begin{note} +An instantiated variable template that has const-qualified type +can have external or module linkage, even if not declared \keyword{extern}. +\end{note} + +\pnum +An unnamed namespace or a namespace declared directly or indirectly within an +unnamed namespace has internal linkage. All other namespaces have external linkage. +The name of an entity that belongs to a namespace scope +that has not been given internal linkage above +and that is the name of +\begin{itemize} +\item a variable; or +\item a function; or +\item +\indextext{class!linkage of}% +a named class\iref{class.pre}, or an unnamed class defined in a +typedef declaration in which the class has the typedef name for linkage +purposes\iref{dcl.typedef}; or +\item +\indextext{enumeration!linkage of}% +a named enumeration\iref{dcl.enum}, or an unnamed enumeration defined +in a typedef declaration in which the enumeration has the typedef name +for linkage purposes\iref{dcl.typedef}; or +\item an unnamed enumeration +that has an enumerator as a name for linkage purposes\iref{dcl.enum}; or +\item a template +\end{itemize} +has its linkage determined as follows: +\begin{itemize} +\item +\indextext{friend function!linkage of}% +if the entity is a function or function template +first declared in a friend declaration and +that declaration is a definition and +the enclosing class is defined within an \grammarterm{export-declaration}, +the name has the same linkage, if any, +as the name of the enclosing class\iref{class.friend}; +\item +otherwise, +\indextext{friend function!linkage of}% +if the entity is a function or function template +declared in a friend declaration and +a corresponding non-friend declaration is reachable, +%FIXME: Which declaration is "that prior declaration"? +%FIXME: "prior" with respect to what? And what about dependent lookup? +the name has the linkage determined from that prior declaration, +\item +otherwise, +if the enclosing namespace has internal linkage, +the name has internal linkage; +\item +otherwise, +if the declaration of the name is +attached to a named module\iref{module.unit} +and is not exported\iref{module.interface}, +the name has module linkage; +\item +otherwise, +the name has external linkage. +\end{itemize} + +\pnum +In addition, +a member function, +a static data member, +a named class or enumeration that inhabits a class scope, or +an unnamed class or enumeration defined in a typedef declaration +that inhabits a class scope +such that the class or enumeration +has the typedef name for linkage purposes\iref{dcl.typedef}, +has the same linkage, if any, as the name of the class of which it is a member. + +\pnum +\begin{example} +\begin{codeblock} +static void f(); +extern "C" void h(); +static int i = 0; // \#1 +void q() { + extern void f(); // internal linkage + extern void g(); // \tcode{::g}, external linkage + extern void h(); // C language linkage + int i; // \#2: \tcode{i} has no linkage + { + extern void f(); // internal linkage + extern int i; // \#3: internal linkage + } +} +\end{codeblock} +Even though the declaration at line \#2 hides the declaration at line \#1, +the declaration at line \#3 still redeclares \#1 and receives internal linkage. +\end{example} + +\pnum +\indextext{linkage!no}% +Names not covered by these rules have no linkage. Moreover, except as +noted, a name declared at block scope\iref{basic.scope.block} has no +linkage. + +\pnum +\indextext{translation unit!name and}% +\indextext{linkage}% +A name used in more than one translation unit can potentially +refer to the same entity in these translation units depending on the +linkage of the name specified in each translation unit. + +\pnum +Two declarations of entities declare the same entity +if, considering declarations of unnamed types to introduce their names +for linkage purposes, if any\iref{dcl.typedef,dcl.enum}, +they correspond\iref{basic.scope.scope}, +have the same target scope that is not a function or template parameter scope, +neither is a name-independent declaration, +and either +\begin{itemize} +\item +they appear in the same translation unit, or +\item +they both declare names with module linkage and are attached to the same module, or +\item +they both declare names with external linkage. +\end{itemize} +\begin{note} +There are other circumstances in which declarations declare the same entity% +\iref{dcl.link,temp.type,temp.spec.partial}. +\end{note} + +\pnum +If a declaration $H$ that declares a name with internal linkage +precedes a declaration $D$ in another translation unit $U$ and +would declare the same entity as $D$ if it appeared in $U$, +the program is ill-formed. +\begin{note} +Such an $H$ can appear only in a header unit. +\end{note} + +\pnum +If two declarations of an entity are +attached to different modules, the program is ill-formed; +no diagnostic is required if neither is reachable from the other. +\begin{example} +\begin{codeblocktu}{\tcode{"decls.h"}} +int f(); // \#1, attached to the global module +int g(); // \#2, attached to the global module +\end{codeblocktu} + +\begin{codeblocktu}{Module interface of \tcode{M}} +module; +#include "decls.h" +export module M; +export using ::f; // OK, does not declare an entity, exports \#1 +int g(); // error: matches \#2, but attached to \tcode{M} +export int h(); // \#3 +export int k(); // \#4 +\end{codeblocktu} + +\begin{codeblocktu}{Other translation unit} +import M; +static int h(); // error: matches \#3 +int k(); // error: matches \#4 +\end{codeblocktu} +\end{example} +As a consequence of these rules, +all declarations of an entity are attached to the same module; +the entity is said to be \defnx{attached}{attached!entity} to that module. + +\pnum +\indextext{consistency!type declaration}% +\indextext{declaration!multiple}% +For any two declarations of an entity $E$: +\begin{itemize} +\item +If one declares $E$ to be a variable or function, +the other shall declare $E$ as one of the same type. +\item +If one declares $E$ to be an enumerator, the other shall do so. +\item +If one declares $E$ to be a namespace, the other shall do so. +\item +If one declares $E$ to be a type, +the other shall declare $E$ to be a type of the same kind\iref{dcl.type.elab}. +\item +If one declares $E$ to be a class template, +the other shall do so with the same kind and +an equivalent \grammarterm{template-head}\iref{temp.over.link}. +\begin{note} +The declarations can supply different default template arguments. +\end{note} +\item +If one declares $E$ to be a function template or +a (partial specialization of a) variable template, +the other shall declare $E$ to be one +with an equivalent \grammarterm{template-head} and type. +\item +If one declares $E$ to be an alias template, +the other shall declare $E$ to be one with +an equivalent \grammarterm{template-head} and \grammarterm{defining-type-id}. +\item +If one declares $E$ to be a concept, the other shall do so. +\end{itemize} +Types are compared after all adjustments of types (during which +typedefs\iref{dcl.typedef} are replaced by their definitions); +declarations for an array +object can specify array types that differ by the presence or absence of +a major array bound\iref{dcl.array}. +No diagnostic is required if neither declaration is reachable from the other. +\begin{example} +\begin{codeblock} +int f(int x, int x); // error: different entities for \tcode{x} +void g(); // \#1 +void g(int); // OK, different entity from \#1 +int g(); // error: same entity as \#1 with different type +void h(); // \#2 +namespace h {} // error: same entity as \#2, but not a function +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Linkage to non-\Cpp{} declarations can be achieved using a +\grammarterm{linkage-specification}\iref{dcl.link}. +\end{note} +\indextext{linkage|)} + +\pnum +A declaration $D$ \defnx{names}{name} an entity $E$ if +\begin{itemize} +\item +$D$ contains a \grammarterm{lambda-expression} whose closure type is $E$, +\item +$E$ is not a function or function template and $D$ contains an +\grammarterm{id-expression}, +\grammarterm{type-specifier}, +\grammarterm{nested-name-specifier}, +\grammarterm{template-name}, or +\grammarterm{concept-name} +denoting $E$, or +\item +$E$ is a function or function template and +$D$ contains an expression that names $E$\iref{basic.def.odr} or +an \grammarterm{id-expression} +that refers to a set of overloads that contains $E$. +\begin{note} +Non-dependent names in an instantiated declaration +do not refer to a set of overloads\iref{temp.res}. +\end{note} +\end{itemize} + +\pnum +A declaration is an \defn{exposure} +if it either names a TU-local entity (defined below), ignoring +\begin{itemize} +\item +the \grammarterm{function-body} +for a non-inline function or function template +(but not the deduced return type +for a (possibly instantiated) definition of a function +with a declared return type that uses a placeholder type\iref{dcl.spec.auto}), +\item +the \grammarterm{initializer} +for a variable or variable template (but not the variable's type), +\item +friend declarations in a class definition, and +\item +any reference to a non-volatile const object or reference +with internal or no linkage initialized with a constant expression +that is not an odr-use\iref{term.odr.use}, +\end{itemize} +or defines a constexpr variable initialized to a TU-local value (defined below). +\begin{note} +An inline function template can be an exposure even though +certain explicit specializations of it would be usable in other translation units. +\end{note} + +\pnum +An entity is \defnx{TU-local}{TU-local!entity} if it is +\begin{itemize} +\item +a type, function, variable, or template that +\begin{itemize} +\item +has a name with internal linkage, or +\item +does not have a name with linkage and is declared, +or introduced by a \grammarterm{lambda-expression}, +within the definition of a TU-local entity, +\end{itemize} +\item +a type with no name that is defined outside a +\grammarterm{class-specifier}, +function body, or +\grammarterm{initializer} +or is introduced by a \grammarterm{defining-type-specifier} +that is used to declare only TU-local entities, +\item +a specialization of a TU-local template, +\item +a specialization of a template with any TU-local template argument, or +\item +a specialization of a template +whose (possibly instantiated) declaration is an exposure. +\begin{note} +A specialization can be produced by implicit or explicit instantiation. +\end{note} +\end{itemize} + +\pnum +A value or object is \defnx{TU-local}{TU-local!value or object} if either +\begin{itemize} +\item +it is, or is a pointer to, +a TU-local function or the object associated with a TU-local variable, or +\item +it is an object of class or array type and +any of its subobjects or +any of the objects or functions +to which its non-static data members of reference type refer +is TU-local and is usable in constant expressions. +\end{itemize} + +\pnum +If a (possibly instantiated) declaration of, or a deduction guide for, +a non-TU-local entity in a module interface unit +(outside the \grammarterm{private-module-fragment}, if any) or +module partition\iref{module.unit} is an exposure, +the program is ill-formed. +Such a declaration in any other context is deprecated\iref{depr.local}. + +\pnum +If a declaration that appears in one translation unit +names a TU-local entity declared +in another translation unit that is not a header unit, +the program is ill-formed. +A declaration instantiated for a template specialization\iref{temp.spec} +appears at the point of instantiation of the specialization\iref{temp.point}. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module A; +static void f() {} +inline void it() { f(); } // error: is an exposure of \tcode{f} +static inline void its() { f(); } // OK +template void g() { its(); } // OK +template void g<0>(); + +decltype(f) *fp; // error: \tcode{f} (though not its type) is TU-local +auto &fr = f; // OK +constexpr auto &fr2 = fr; // error: is an exposure of \tcode{f} +constexpr static auto fp2 = fr; // OK + +struct S { void (&ref)(); } s{f}; // OK, value is TU-local +constexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-local + +static auto x = []{f();}; // OK +auto x2 = x; // error: the closure type is TU-local +int y = ([]{f();}(),0); // error: the closure type is not TU-local +int y2 = (x,0); // OK + +namespace N { + struct A {}; + void adl(A); + static void adl(int); +} +void adl(double); + +inline void h(auto x) { adl(x); } // OK, but certain specializations are exposures +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +module A; +void other() { + g<0>(); // OK, specialization is explicitly instantiated + g<1>(); // error: instantiation uses TU-local \tcode{its} + h(N::A{}); // error: overload set contains TU-local \tcode{N::adl(int)} + h(0); // OK, calls \tcode{adl(double)} + adl(N::A{}); // OK; \tcode{N::adl(int)} not found, calls \tcode{N::adl(N::A)} + fr(); // OK, calls \tcode{f} + constexpr auto ptr = fr; // error: \tcode{fr} is not usable in constant expressions here +} +\end{codeblocktu} +\end{example} + \indextext{conventions!lexical|)} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 86ab73dda5..8ca834f9d4 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -3188,16 +3188,6 @@ \tcode{\#define} or \tcode{\#undef} names declared in any standard library header. -\pnum -\indextext{unit!translation}% -A translation unit shall not \tcode{\#define} or \tcode{\#undef} -names lexically identical -to keywords, -to the identifiers listed in \tref{lex.name.special}, or -to the \grammarterm{attribute-token}{s} described in~\ref{dcl.attr}, -except that the names \tcode{likely} and \tcode{unlikely} may be -defined as function-like macros~\iref{cpp.replace}. - \rSec4[extern.names]{External linkage} \pnum diff --git a/source/modules.tex b/source/modules.tex index 2ed009a3b6..38ecafe6fa 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -6,6 +6,10 @@ \rSec1[module.unit]{Module units and purviews} \begin{bnf} +\nontermdef{translation-unit}\br + \opt{declaration-seq}\br + \opt{global-module-fragment} module-declaration \opt{declaration-seq} \opt{private-module-fragment} + \nontermdef{module-declaration}\br \opt{export-keyword} module-keyword module-name \opt{module-partition} \opt{attribute-specifier-seq} \terminal{;} \end{bnf} @@ -26,6 +30,10 @@ module-name-qualifier identifier \terminal{.} \end{bnf} +\pnum +\indextext{translation unit}% +A translation unit\iref{lex.phases} consists of a sequence of declarations\iref{dcl.pre}. + \pnum A \defn{module unit} is a translation unit that contains a \grammarterm{module-declaration}. @@ -327,8 +335,9 @@ \begin{note} Names introduced by exported declarations have either external linkage or no 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}. +Namespace-scope declarations exported by a module can be found by +name lookup\iref{basic.lookup} +in any translation unit importing that module. Class and enumeration member names can be found by name lookup in any context in which a definition of the type is reachable. \end{note} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 2b9e3e7e05..c149eed4d5 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -272,1738 +272,1738 @@ has been replaced. \end{example} -\rSec1[cpp.cond]{Conditional inclusion}% -\indextext{preprocessing directive!conditional inclusion}% -\indextext{inclusion!conditional|see{preprocessing directive, conditional inclusion}} +\rSec1[cpp.module]{Module directive} +\indextext{preprocessing directive!module}% -\indextext{\idxcode{defined}}% \begin{bnf} -\nontermdef{defined-macro-expression}\br - \terminal{defined} identifier\br - \terminal{defined (} identifier \terminal{)} +\nontermdef{pp-module}\br + \opt{\keyword{export}} \keyword{module} \opt{pp-tokens} \terminal{;} new-line \end{bnf} -\begin{bnf} -\nontermdef{h-preprocessing-token}\br - \textnormal{any \grammarterm{preprocessing-token} other than \terminal{>}} -\end{bnf} +\pnum +A \grammarterm{pp-module} shall not +appear in a context where \tcode{module} +or (if it is the first token of the \grammarterm{pp-module}) \tcode{export} +is an identifier defined as an object-like macro. -\begin{bnf} -\nontermdef{h-pp-tokens}\br - h-preprocessing-token\br - h-pp-tokens h-preprocessing-token -\end{bnf} +\pnum +The \grammarterm{pp-tokens}, if any, of a \grammarterm{pp-module} +shall be of the form: +\begin{ncsimplebnf} +pp-module-name \opt{pp-module-partition} \opt{pp-tokens} +\end{ncsimplebnf} +where the \grammarterm{pp-tokens} (if any) shall not begin with +a \tcode{(} preprocessing token and +the grammar non-terminals are defined as: +\begin{ncbnf} +\nontermdef{pp-module-name}\br + \opt{pp-module-name-qualifier} identifier +\end{ncbnf} +\begin{ncbnf} +\nontermdef{pp-module-partition}\br + \terminal{:} \opt{pp-module-name-qualifier} identifier +\end{ncbnf} +\begin{ncbnf} +\nontermdef{pp-module-name-qualifier}\br + identifier \terminal{.}\br + pp-module-name-qualifier identifier \terminal{.} +\end{ncbnf} +No \grammarterm{identifier} in +the \grammarterm{pp-module-name} or \grammarterm{pp-module-partition} +shall currently be defined as an object-like macro. -\begin{bnf} -\nontermdef{header-name-tokens}\br - string-literal\br - \terminal{<} h-pp-tokens \terminal{>} -\end{bnf} +\pnum +Any preprocessing tokens after the \tcode{module} preprocessing token +in the \tcode{module} directive are processed just as in normal text. +\begin{note} +Each identifier currently defined as a macro name +is replaced by its replacement list of preprocessing tokens. +\end{note} -\indextext{\idxxname{has_include}}% -\begin{bnf} -\nontermdef{has-include-expression}\br - \terminal{\xname{has_include}} \terminal{(} header-name \terminal{)}\br - \terminal{\xname{has_include}} \terminal{(} header-name-tokens \terminal{)} -\end{bnf} +\pnum +The \tcode{module} and \tcode{export} (if it exists) preprocessing tokens +are replaced by the \grammarterm{module-keyword} and +\grammarterm{export-keyword} preprocessing tokens respectively. +\begin{note} +This makes the line no longer a directive +so it is not removed at the end of phase 4. +\end{note} + +\rSec1[cpp.import]{Header unit importation} +\indextext{header unit!preprocessing}% +\indextext{preprocessing directive!import}% +\indextext{macro!import|(}% -\indextext{\idxxname{has_cpp_attribute}}% \begin{bnf} -\nontermdef{has-attribute-expression}\br - \terminal{\xname{has_cpp_attribute} (} pp-tokens \terminal{)} +\nontermdef{pp-import}\br + \opt{\keyword{export}} \keyword{import} header-name \opt{pp-tokens} \terminal{;} new-line\br + \opt{\keyword{export}} \keyword{import} header-name-tokens \opt{pp-tokens} \terminal{;} new-line\br + \opt{\keyword{export}} \keyword{import} pp-tokens \terminal{;} new-line \end{bnf} \pnum -The expression that controls conditional inclusion -shall be an integral constant expression except that -identifiers -(including those lexically identical to keywords) -are interpreted as described below -\begin{footnote} -Because the controlling constant expression is evaluated -during translation phase 4, -all identifiers either are or are not macro names --- -there simply are no keywords, enumeration constants, etc. -\end{footnote} -and it may contain zero or more \grammarterm{defined-macro-expression}{s} and/or -\grammarterm{has-include-expression}{s} and/or -\grammarterm{has-attribute-expression}{s} as unary operator expressions. - -\pnum -A \grammarterm{defined-macro-expression} evaluates to \tcode{1} -if the identifier is currently defined -as a macro name -(that is, if it is predefined -or if it has one or more active macro definitions\iref{cpp.import}, -for example because -it has been the subject of a -\tcode{\#define} -preprocessing directive -without an intervening -\tcode{\#undef} -directive with the same subject identifier), \tcode{0} if it is not. +A \grammarterm{pp-import} shall not +appear in a context where \tcode{import} +or (if it is the first token of the \grammarterm{pp-import}) \tcode{export} +is an identifier defined as an object-like macro. \pnum -The second form of \grammarterm{has-include-expression} -is considered only if the first form does not match, -in which case the preprocessing tokens are processed just as in normal text. +The preprocessing tokens after the \tcode{import} preprocessing token +in the \tcode{import} \grammarterm{control-line} +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). +\begin{note} +An \tcode{import} directive +matching the first two forms of a \grammarterm{pp-import} +instructs the preprocessor to import macros +from the header unit\iref{module.import} +denoted by the \grammarterm{header-name}, +as described below. +\end{note} +\indextext{point of!macro import|see{macro, point of import}}% +The \defnx{point of macro import}{macro!point of import} for the +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. \pnum -The header or source file identified by -the parenthesized preprocessing token sequence -in each contained \grammarterm{has-include-expression} -is searched for as if that preprocessing token sequence -were the \grammarterm{pp-tokens} in a \tcode{\#include} directive, -except that no further macro expansion is performed. -If such a directive would not satisfy the syntactic requirements -of a \tcode{\#include} directive, the program is ill-formed. -The \grammarterm{has-include-expression} evaluates -to \tcode{1} if the search for the source file succeeds, and -to \tcode{0} if the search fails. +If a \grammarterm{pp-import} is produced by source file inclusion +(including by the rewrite produced +when a \tcode{\#include} directive names an importable header) +while processing the \grammarterm{group} of a \grammarterm{module-file}, +the program is ill-formed. \pnum -Each \grammarterm{has-attribute-expression} is replaced by -a non-zero \grammarterm{pp-number} -matching the form of an \grammarterm{integer-literal} -if the implementation supports an attribute -with the name specified by interpreting -the \grammarterm{pp-tokens}, after macro expansion, -as an \grammarterm{attribute-token}, -and by \tcode{0} otherwise. -The program is ill-formed if the \grammarterm{pp-tokens} -do not match the form of an \grammarterm{attribute-token}. +In all three forms of \grammarterm{pp-import}, +the \tcode{import} and \tcode{export} (if it exists) preprocessing tokens +are replaced by the \grammarterm{import-keyword} and +\grammarterm{export-keyword} preprocessing tokens respectively. +\begin{note} +This makes the line no longer a directive +so it is not removed at the end of phase 4. +\end{note} +Additionally, in the second form of \grammarterm{pp-import}, +a \grammarterm{header-name} token is formed as if +the \grammarterm{header-name-tokens} +were the \grammarterm{pp-tokens} of a \tcode{\#include} directive. +The \grammarterm{header-name-tokens} are replaced by +the \grammarterm{header-name} token. +\begin{note} +This ensures that imports are treated consistently by +the preprocessor and later phases of translation. +\end{note} \pnum -For an attribute specified in this document, -it is \impldef{value of \grammarterm{has-attribute-expression} -for standard attributes} -whether the value of the \grammarterm{has-attribute-expression} -is \tcode{0} or is given by \tref{cpp.cond.ha}. -For other attributes recognized by the implementation, -the value is -\impldef{value of \grammarterm{has-attribute-expression} -for non-standard attributes}. +Each \tcode{\#define} directive encountered when preprocessing +each translation unit in a program results in a distinct +\defnx{macro definition}{macro!definition}. \begin{note} -It is expected -that the availability of an attribute can be detected by any non-zero result. +A predefined macro name\iref{cpp.predefined} +is not introduced by a \tcode{\#define} directive. +Implementations providing mechanisms to predefine additional macros +are encouraged to not treat them +as being introduced by a \tcode{\#define} directive. \end{note} +Each macro definition has at most one point of definition in +each translation unit and at most one point of undefinition, as follows: +\begin{itemize} +\item +\indextext{point of!macro definition|see{macro, point of definition}}% +The \defnx{point of definition}{macro!point of definition} +of a macro definition within a translation unit $T$ is +\begin{itemize} +\item +if the \tcode{\#define} directive of the macro definition occurs within $T$, +the point at which that directive occurs, or otherwise, +\item +if the macro name is not lexically identical to a keyword\iref{lex.key} +or to the \grammarterm{identifier}{s} \tcode{module} or \tcode{import}, +the first point of macro import in $T$ of a header unit +containing a point of definition for the macro definition, if any. +\end{itemize} +In the latter case, the macro is said +to be \defnx{imported}{macro!import} from the header unit. -\begin{floattable}{\xname{has_cpp_attribute} values}{cpp.cond.ha} -{ll} -\topline -\lhdr{Attribute} & \rhdr{Value} \\ \rowsep -\tcode{assume} & \tcode{202207L} \\ -\tcode{carries_dependency} & \tcode{200809L} \\ -\tcode{deprecated} & \tcode{201309L} \\ -\tcode{fallthrough} & \tcode{201603L} \\ -\tcode{likely} & \tcode{201803L} \\ -\tcode{maybe_unused} & \tcode{201603L} \\ -\tcode{no_unique_address} & \tcode{201803L} \\ -\tcode{nodiscard} & \tcode{201907L} \\ -\tcode{noreturn} & \tcode{200809L} \\ -\tcode{unlikely} & \tcode{201803L} \\ -\end{floattable} +\item +\indextext{point of!macro undefinition|see{macro, point of undefinition}}% +The \defnx{point of undefinition}{macro!point of undefinition} +of a macro definition within a translation unit +is the first point at which a \tcode{\#undef} directive naming the macro occurs +after its point of definition, or the first point +of macro import of a header unit containing a point of undefinition for the +macro definition, whichever (if any) occurs first. +\end{itemize} \pnum -The -\tcode{\#ifdef}, \tcode{\#ifndef}, \tcode{\#elifdef}, and \tcode{\#elifndef} -directives, and -the \tcode{defined} conditional inclusion operator, -shall treat \xname{has_include} and \xname{has_cpp_attribute} -as if they were the names of defined macros. -The identifiers \xname{has_include} and \xname{has_cpp_attribute} -shall not appear in any context not mentioned in this subclause. - -\pnum -Each preprocessing token that remains (in the list of preprocessing tokens that -will become the controlling expression) -after all macro replacements have occurred -shall be in the lexical form of a token\iref{lex.token}. - -\pnum -Preprocessing directives of the forms -\begin{ncsimplebnf}\obeyspaces -\indextext{\idxcode{\#if}}% -\terminal{\# if } constant-expression new-line \opt{group}\br -\indextext{\idxcode{\#elif}}% -\terminal{\# elif } constant-expression new-line \opt{group} -\end{ncsimplebnf} -check whether the controlling constant expression evaluates to nonzero. - -\pnum -Prior to evaluation, -macro invocations in the list of preprocessing tokens -that will become the controlling constant expression -are replaced -(except for those macro names modified by the -\tcode{defined} -unary operator), -just as in normal text. -If the token -\tcode{defined} -is generated as a result of this replacement process -or use of the -\tcode{defined} -unary operator does not match one of the two specified forms -prior to macro replacement, -the behavior is undefined. +\indextext{active macro directive|see{macro, active}}% +A macro directive is \defnx{active}{macro!active} at a source location +if it has a point of definition in that translation unit preceding the location, +and does not have a point of undefinition in that translation unit preceding +the location. \pnum -After all replacements due to macro expansion and -evaluations of -\grammarterm{defined-macro-expression}s, -\grammarterm{has-include-expression}s, and -\grammarterm{has-attribute-expression}s -have been performed, -all remaining identifiers and keywords, -except for -\tcode{true} -and -\tcode{false}, -are replaced with the \grammarterm{pp-number} -\tcode{0}, -and then each preprocessing token is converted into a token. +If a macro would be replaced or redefined, and multiple macro definitions +are active for that macro name, the active macro definitions shall all be +valid redefinitions of the same macro\iref{cpp.replace}. \begin{note} -An alternative -token\iref{lex.digraph} is not an identifier, -even when its spelling consists entirely of letters and underscores. -Therefore it is not subject to this replacement. +The relative order of \grammarterm{pp-import}{s} has no bearing on whether a +particular macro definition is active. \end{note} \pnum -The resulting tokens comprise the controlling constant expression -which is evaluated according to the rules of~\ref{expr.const} -using arithmetic that has at least the ranges specified -in~\ref{support.limits}. For the purposes of this token conversion and evaluation -all signed and unsigned integer types -act as if they have the same representation as, respectively, -\tcode{intmax_t} or \tcode{uintmax_t}\iref{cstdint.syn}. -\begin{note} -Thus on an -implementation where \tcode{std::numeric_limits::max()} is \tcode{0x7FFF} -and \tcode{std::numeric_limits::max()} is \tcode{0xFFFF}, -the integer literal \tcode{0x8000} is signed and positive within a \tcode{\#if} -expression even though it is unsigned in translation phase -7\iref{lex.phases}. -\end{note} -This includes interpreting \grammarterm{character-literal}s -according to the rules in \ref{lex.ccon}. -\begin{note} -The associated character encodings of literals are the same -in \tcode{\#if} and \tcode{\#elif} directives and in any expression. -\end{note} -Each subexpression with type -\tcode{bool} -is subjected to integral promotion before processing continues. +\begin{example} +\begin{codeblocktu}{Importable header \tcode{"a.h"}} +#define X 123 // \#1 +#define Y 45 // \#2 +#define Z a // \#3 +#undef X // point of undefinition of \#1 in \tcode{"a.h"} +\end{codeblocktu} -\pnum -Preprocessing directives of the forms -\begin{ncsimplebnf}\obeyspaces -\terminal{\# ifdef } identifier new-line \opt{group}\br -\indextext{\idxcode{\#ifdef}}% -\terminal{\# ifndef } identifier new-line \opt{group}\br -\indextext{\idxcode{\#ifndef}}% -\terminal{\# elifdef } identifier new-line \opt{group}\br -\indextext{\idxcode{\#elifdef}}% -\terminal{\# elifndef} identifier new-line \opt{group} -\indextext{\idxcode{\#elifndef}}% -\end{ncsimplebnf} -check whether the identifier is or is not currently defined as a macro name. -Their conditions are equivalent to -\tcode{\#if} \tcode{defined} \grammarterm{identifier}, -\tcode{\#if} \tcode{!defined} \grammarterm{identifier}, -\tcode{\#elif} \tcode{defined} \grammarterm{identifier}, and -\tcode{\#elif} \tcode{!defined} \grammarterm{identifier}, -respectively. +\begin{codeblocktu}{Importable header \tcode{"b.h"}} +import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"b.h"} +#define X 456 // OK, \#1 is not active +#define Y 6 // error: \#2 is active +\end{codeblocktu} -\pnum -Each directive's condition is checked in order. -If it evaluates to false (zero), -the group that it controls is skipped: -directives are processed only through the name that determines -the directive in order to keep track of the level -of nested conditionals; -the rest of the directives' preprocessing tokens are ignored, -as are the other preprocessing tokens in the group. -Only the first group -whose control condition evaluates to true (nonzero) is processed; -any following groups are skipped and their controlling directives -are processed as if they were in a group that is skipped. -If none of the conditions evaluates to true, -and there is a -\tcode{\#else} -\indextext{\idxcode{\#else}}% -directive, -the group controlled by the -\tcode{\#else} -is processed; lacking a -\tcode{\#else} -directive, all the groups until the -\tcode{\#endif} -\indextext{\idxcode{\#endif}}% -are skipped.% -\begin{footnote} -As indicated by the syntax, -a preprocessing token cannot follow a -\tcode{\#else} -or -\tcode{\#endif} -directive before the terminating new-line character. -However, -comments can appear anywhere in a source file, -including within a preprocessing directive. -\end{footnote} +\begin{codeblocktu}{Importable header \tcode{"c.h"}} +#define Y 45 // \#4 +#define Z c // \#5 +\end{codeblocktu} -\pnum -\begin{example} -This demonstrates a way to include a library \tcode{optional} facility -only if it is available: +\begin{codeblocktu}{Importable header \tcode{"d.h"}} +import "c.h"; // point of definition of \#4 and \#5 in \tcode{"d.h"} +\end{codeblocktu} -\begin{codeblock} -#if __has_include() -# include -# if __cpp_lib_optional >= 201603 -# define have_optional 1 -# endif -#elif __has_include() -# include -# if __cpp_lib_experimental_optional >= 201411 -# define have_optional 1 -# define experimental_optional 1 -# endif -#endif -#ifndef have_optional -# define have_optional 0 -#endif -\end{codeblock} -\end{example} +\begin{codeblocktu}{Importable header \tcode{"e.h"}} +import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"e.h"} +import "d.h"; // point of definition of \#4 and \#5 in \tcode{"e.h"} +int a = Y; // OK, active macro definitions \#2 and \#4 are valid redefinitions +int c = Z; // error: active macro definitions \#3 and \#5 are not valid redefinitions of \tcode{Z} +\end{codeblocktu} -\pnum -\begin{example} -This demonstrates a way to use the attribute \tcode{[[acme::deprecated]]} -only if it is available. -\begin{codeblock} -#if __has_cpp_attribute(acme::deprecated) -# define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]] -#else -# define ATTR_DEPRECATED(msg) [[deprecated(msg)]] -#endif -ATTR_DEPRECATED("This function is deprecated") void anvil(); -\end{codeblock} -\end{example} +\begin{codeblocktu}{Module unit \tcode{f}} +export module f; +export import "a.h"; -\rSec1[cpp.include]{Source file inclusion} -\indextext{preprocessing directive!header inclusion} -\indextext{preprocessing directive!source-file inclusion} -\indextext{inclusion!source file|see{preprocessing directive, source-file inclusion}}% -\indextext{\idxcode{\#include}}% +int a = Y; // OK +\end{codeblocktu} -\pnum -A -\tcode{\#include} -directive shall identify a header or source file -that can be processed by the implementation. +\begin{codeblocktu}{Translation unit \tcode{\#1}} +import f; +int x = Y; // error: \tcode{Y} is neither a defined macro nor a declared name +\end{codeblocktu} +\end{example} +\indextext{macro!import|)} + +\rSec1[cpp.null]{Null directive}% +\indextext{preprocessing directive!null} \pnum A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# include <} h-char-sequence \terminal{>} new-line +\terminal{\#} new-line \end{ncsimplebnf} -searches a sequence of -\impldef{sequence of places searched for a header} -places -for a header identified uniquely by the specified sequence -between the -\tcode{<} -and -\tcode{>} -delimiters, -and causes the replacement of that -directive by the entire contents of the header. -How the places are specified -or the header identified -is \impldef{search locations for \tcode{<>} header}. +has no effect. + +\rSec1[cpp.error]{Diagnostic directives}% +\indextext{preprocessing directive!error}% +\indextext{preprocessing directive!diagnostic}% +\indextext{preprocessing directive!warning}% +\indextext{\idxcode{\#error}|see{preprocessing directive, error}} \pnum A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# include "} q-char-sequence \terminal{"} new-line +\terminal{\# error} \opt{pp-tokens} new-line \end{ncsimplebnf} -causes the replacement of that -directive by the entire contents of the -source file identified by the specified sequence between the -\tcode{"} -delimiters. -The named source file is searched for in an -\impldef{manner of search for included source file} -manner. -If this search is not supported, -or if the search fails, -the directive is reprocessed as if it read +renders the program ill-formed. +A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# include <} h-char-sequence \terminal{>} new-line +\terminal{\# warning} \opt{pp-tokens} new-line \end{ncsimplebnf} -with the identical contained sequence (including -\tcode{>} -characters, if any) from the original directive. +requires the implementation to produce at least one diagnostic message +for the preprocessing translation unit\iref{intro.compliance.general}. +\recommended +Any diagnostic message caused by either of these directives +should include the specified sequence of preprocessing tokens. + +\rSec1[cpp.line]{Line control}% +\indextext{preprocessing directive!line control}% +\indextext{\idxcode{\#line}|see{preprocessing directive, line control}} + +\pnum +The \grammarterm{string-literal} of a +\tcode{\#line} +directive, if present, +shall be a character string literal. + +\pnum +The +\defn{line number} +of the current source line is one greater than +the number of new-line characters read or introduced +in translation phase 1\iref{lex.phases} +while processing the source file to the current token. \pnum A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# include} pp-tokens new-line +\terminal{\# line} digit-sequence new-line \end{ncsimplebnf} -(that does not match one of the two previous forms) is permitted. +causes the implementation to behave as if +the following sequence of source lines begins with a +source line that has a line number as specified +by the digit sequence (interpreted as a decimal integer). +If the digit sequence specifies zero +or a number greater than 2147483647, +the behavior is undefined. + +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# line} digit-sequence \terminal{"} \opt{s-char-sequence} \terminal{"} new-line +\end{ncsimplebnf} +sets the presumed line number similarly and changes the +presumed name of the source file to be the contents +of the character string literal. + +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# line} pp-tokens new-line +\end{ncsimplebnf} +(that does not match one of the two previous forms) +is permitted. The preprocessing tokens after -\tcode{include} -in the directive are processed just as in normal text -(i.e., each identifier currently defined as a macro name is replaced by its +\tcode{line} +on the directive are processed just as in normal text +(each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match -one of the two previous forms, the behavior is -undefined. -\begin{footnote} -Note that adjacent \grammarterm{string-literal}s are not concatenated into -a single \grammarterm{string-literal} -(see the translation phases in~\ref{lex.phases}); -thus, an expansion that results in two \grammarterm{string-literal}s is an -invalid directive. -\end{footnote} -The method by which a sequence of preprocessing tokens between a -\tcode{<} -and a -\tcode{>} -preprocessing token pair or a pair of -\tcode{"} -characters is combined into a single header name -preprocessing token is \impldef{search locations for \tcode{""""} header}. +one of the two previous forms, the behavior is undefined; +otherwise, the result is processed as appropriate. -\pnum -The implementation shall provide unique mappings for -sequences consisting of one or more -\grammarterm{nondigit}{s} or \grammarterm{digit}{s}\iref{lex.name} -followed by a period -(\tcode{.}) -and a single -\grammarterm{nondigit}. -The first character shall not be a \grammarterm{digit}. -The implementation may ignore distinctions of alphabetical case. +\rSec1[cpp.pragma]{Pragma directive}% +\indextext{preprocessing directive!pragma}% +\indextext{\idxcode{\#pragma}|see{preprocessing directive, pragma}} \pnum -A -\tcode{\#include} -preprocessing directive may appear -in a source file that has been read because of a -\tcode{\#include} -directive in another file, -up to an \impldef{nesting limit for \tcode{\#include} directives} nesting limit. +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# pragma} \opt{pp-tokens} new-line +\end{ncsimplebnf} +causes the implementation to behave +in an \impldef{\tcode{\#pragma}} manner. +The behavior may cause translation to fail or cause the translator or +the resulting program to behave in a non-conforming manner. +Any pragma that is not recognized by the implementation is ignored. + +\rSec1[cpp.pragma.op]{Pragma operator}% +\indextext{macro!pragma operator}% +\indextext{operator!pragma|see{macro, pragma operator}} \pnum -If the header identified by the \grammarterm{header-name} -denotes an importable header\iref{module.import}, -it is -\impldef{whether source file inclusion of importable header -is replaced with \tcode{import} directive} -whether the \tcode{\#include} preprocessing directive -is instead replaced by an \tcode{import} directive\iref{cpp.import} of the form +A unary operator expression of the form: \begin{ncbnf} -\terminal{import} header-name \terminal{;} new-line +\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 +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 +to produce preprocessing tokens that are executed as if they were the +\grammarterm{pp-tokens} in a pragma directive. The original four preprocessing +tokens in the unary operator expression are removed. \pnum -\begin{note} -An implementation can provide a mechanism for making arbitrary -source files available to the \tcode{< >} search. -However, using the \tcode{< >} form for headers provided -with the implementation and the \tcode{" "} form for sources -outside the control of the implementation -achieves wider portability. For instance: - +\begin{example} \begin{codeblock} -#include -#include -#include "usefullib.h" -#include "myprog.h" +#pragma listing on "..\listing.dir" +\end{codeblock} +can also be expressed as: +\begin{codeblock} +_Pragma ( "listing on \"..\\listing.dir\"" ) +\end{codeblock} +The latter form is processed in the same way whether it appears literally +as shown, or results from macro replacement, as in: +\begin{codeblock} +#define LISTING(x) PRAGMA(listing on #x) +#define PRAGMA(x) _Pragma(#x) + +LISTING( ..\listing.dir ) \end{codeblock} +\end{example} +\indextext{preprocessing directive|)} -\end{note} +\rSec1[cpp.replace]{Macro replacement}% + +\rSec2[cpp.replace.general]{General}% +\indextext{macro!replacement|(}% +\indextext{replacement!macro|see{macro, replacement}}% +\indextext{preprocessing directive!macro replacement|see{macro, replacement}} \pnum -\begin{example} -This illustrates macro-replaced -\tcode{\#include} -directives: +\indextext{macro!replacement list}% +Two replacement lists are identical if and only if +the preprocessing tokens in both have +the same number, ordering, spelling, and whitespace separation, +where all whitespace separations are considered identical. + +\pnum +An identifier currently defined as an +\indextext{macro!object-like}% +object-like macro (see below) may be redefined by another +\tcode{\#define} +preprocessing directive provided that the second definition is an +object-like macro definition and the two replacement lists +are identical, otherwise the program is ill-formed. +Likewise, an identifier currently defined as a +\indextext{macro!function-like}% +function-like macro (see below) may be redefined by another +\tcode{\#define} +preprocessing directive provided that the second definition is a +function-like macro definition that has the same number and spelling +of parameters, +and the two replacement lists are identical, +otherwise the program is ill-formed. +\pnum +\begin{example} +The following sequence is valid: \begin{codeblock} -#if VERSION == 1 - #define INCFILE "vers1.h" -#elif VERSION == 2 - #define INCFILE "vers2.h" // and so on -#else - #define INCFILE "versN.h" -#endif -#include INCFILE +#define OBJ_LIKE (1-1) +#define OBJ_LIKE @\tcode{/* whitespace */ (1-1) /* other */}@ +#define FUNC_LIKE(a) ( a ) +#define FUNC_LIKE( a )( @\tcode{/* note the whitespace */ \textbackslash}@ + a @\tcode{/* other stuff on this line}@ + @\tcode{*/}@ ) +\end{codeblock} +But the following redefinitions are invalid: +\begin{codeblock} +#define OBJ_LIKE (0) // different token sequence +#define OBJ_LIKE (1 - 1) // different whitespace +#define FUNC_LIKE(b) ( a ) // different parameter usage +#define FUNC_LIKE(b) ( b ) // different parameter spelling \end{codeblock} \end{example} -\rSec1[cpp.module]{Module directive} -\indextext{preprocessing directive!module}% +\pnum +\indextext{macro!replacement list}% +There shall be whitespace between the identifier and the replacement list +in the definition of an object-like macro. -\begin{bnf} -\nontermdef{pp-module}\br - \opt{\keyword{export}} \keyword{module} \opt{pp-tokens} \terminal{;} new-line -\end{bnf} +\pnum +If the \grammarterm{identifier-list} in the macro definition does not end with +an ellipsis, the number of arguments (including those arguments consisting +of no preprocessing tokens) +in an invocation of a function-like macro shall +equal the number of parameters in the macro definition. +Otherwise, there shall be at least as many arguments in the invocation as there are +parameters in the macro definition (excluding the \tcode{...}). There +shall exist a +\tcode{)} +preprocessing token that terminates the invocation. \pnum -A \grammarterm{pp-module} shall not -appear in a context where \tcode{module} -or (if it is the first token of the \grammarterm{pp-module}) \tcode{export} -is an identifier defined as an object-like macro. +\indextext{__va_args__@\mname{VA_ARGS}}% +\indextext{__va_opt__@\mname{VA_OPT}}% +The identifiers \mname{VA_ARGS} and \mname{VA_OPT} +shall occur only in the \grammarterm{replacement-list} +of a function-like macro that uses the ellipsis notation in the parameters. \pnum -The \grammarterm{pp-tokens}, if any, of a \grammarterm{pp-module} -shall be of the form: -\begin{ncsimplebnf} -pp-module-name \opt{pp-module-partition} \opt{pp-tokens} -\end{ncsimplebnf} -where the \grammarterm{pp-tokens} (if any) shall not begin with -a \tcode{(} preprocessing token and -the grammar non-terminals are defined as: -\begin{ncbnf} -\nontermdef{pp-module-name}\br - \opt{pp-module-name-qualifier} identifier -\end{ncbnf} -\begin{ncbnf} -\nontermdef{pp-module-partition}\br - \terminal{:} \opt{pp-module-name-qualifier} identifier -\end{ncbnf} -\begin{ncbnf} -\nontermdef{pp-module-name-qualifier}\br - identifier \terminal{.}\br - pp-module-name-qualifier identifier \terminal{.} -\end{ncbnf} -No \grammarterm{identifier} in -the \grammarterm{pp-module-name} or \grammarterm{pp-module-partition} -shall currently be defined as an object-like macro. +A parameter identifier in a function-like macro +shall be uniquely declared within its scope. \pnum -Any preprocessing tokens after the \tcode{module} preprocessing token -in the \tcode{module} directive are processed just as in normal text. -\begin{note} -Each identifier currently defined as a macro name -is replaced by its replacement list of preprocessing tokens. -\end{note} +The identifier immediately following the +\tcode{define} +is called the +\indextext{name!macro|see{macro, name}}% +\defnx{macro name}{macro!name}. +There is one name space for macro names. +Any whitespace characters preceding or following the +replacement list of preprocessing tokens are not considered +part of the replacement list for either form of macro. \pnum -The \tcode{module} and \tcode{export} (if it exists) preprocessing tokens -are replaced by the \grammarterm{module-keyword} and -\grammarterm{export-keyword} preprocessing tokens respectively. -\begin{note} -This makes the line no longer a directive -so it is not removed at the end of phase 4. -\end{note} +If a +\indextext{\#\#0 operator@\tcode{\#} operator} +\tcode{\#} +preprocessing token, +followed by an identifier, +occurs lexically +at the point at which a preprocessing directive can begin, +the identifier is not subject to macro replacement. -\rSec1[cpp.import]{Header unit importation} -\indextext{header unit!preprocessing}% -\indextext{preprocessing directive!import}% -\indextext{macro!import|(}% +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# define} identifier replacement-list new-line +\indextext{\idxcode{\#define}}% +\end{ncsimplebnf} +defines an +\defnadj{object-like}{macro} that +causes each subsequent instance of the macro name +\begin{footnote} +Since, by macro-replacement time, +all \grammarterm{character-literal}s and \grammarterm{string-literal}s are preprocessing tokens, +not sequences possibly containing identifier-like subsequences +(see \ref{lex.phases}, translation phases), +they are never scanned for macro names or parameters. +\end{footnote} +to be replaced by the replacement list of preprocessing tokens +that constitute the remainder of the directive. +\begin{footnote} +An alternative token\iref{lex.operators} is not an identifier, +even when its spelling consists entirely of letters and underscores. +Therefore it is not possible to define a macro +whose name is the same as that of an alternative token. +\end{footnote} +The replacement list is then rescanned for more macro names as +specified below. -\begin{bnf} -\nontermdef{pp-import}\br - \opt{\keyword{export}} \keyword{import} header-name \opt{pp-tokens} \terminal{;} new-line\br - \opt{\keyword{export}} \keyword{import} header-name-tokens \opt{pp-tokens} \terminal{;} new-line\br - \opt{\keyword{export}} \keyword{import} pp-tokens \terminal{;} new-line -\end{bnf} +\pnum +\begin{example} +The simplest use of this facility is to define a ``manifest constant'', +as in +\begin{codeblock} +#define TABSIZE 100 +int table[TABSIZE]; +\end{codeblock} +\end{example} \pnum -A \grammarterm{pp-import} shall not -appear in a context where \tcode{import} -or (if it is the first token of the \grammarterm{pp-import}) \tcode{export} -is an identifier defined as an object-like macro. +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# define} identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br +\terminal{\# define} identifier lparen \terminal{...} \terminal{)} replacement-list new-line\br +\terminal{\# define} identifier lparen identifier-list \terminal{, ...} \terminal{)} replacement-list new-line +\end{ncsimplebnf} +defines a \defnadj{function-like}{macro} +with parameters, whose use is +similar syntactically to a function call. +The parameters +\indextext{parameter!macro}% +are specified by the optional list of identifiers. +Each subsequent instance of the function-like macro name followed by a +\tcode{(} +as the next preprocessing token +introduces the sequence of preprocessing tokens that is replaced +by the replacement list in the definition +(an invocation of the macro). +\indextext{invocation!macro}% +The replaced sequence of preprocessing tokens is terminated by the matching +\tcode{)} +preprocessing token, skipping intervening matched pairs of left and +right parenthesis preprocessing tokens. +Within the sequence of preprocessing tokens making up an invocation +of a function-like macro, +new-line is considered a normal whitespace character. \pnum -The preprocessing tokens after the \tcode{import} preprocessing token -in the \tcode{import} \grammarterm{control-line} -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). -\begin{note} -An \tcode{import} directive -matching the first two forms of a \grammarterm{pp-import} -instructs the preprocessor to import macros -from the header unit\iref{module.import} -denoted by the \grammarterm{header-name}, -as described below. -\end{note} -\indextext{point of!macro import|see{macro, point of import}}% -The \defnx{point of macro import}{macro!point of import} for the -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. +\indextext{macro!function-like!arguments}% +The sequence of preprocessing tokens +bounded by the outside-most matching parentheses +forms the list of arguments for the function-like macro. +The individual arguments within the list +are separated by comma preprocessing tokens, +but comma preprocessing tokens between matching +inner parentheses do not separate arguments. +If there are sequences of preprocessing tokens within the list of +arguments that would otherwise act as preprocessing directives, +\begin{footnote} +A \grammarterm{conditionally-supported-directive} is a preprocessing directive regardless of whether the implementation supports it. +\end{footnote} +the behavior is undefined. \pnum -If a \grammarterm{pp-import} is produced by source file inclusion -(including by the rewrite produced -when a \tcode{\#include} directive names an importable header) -while processing the \grammarterm{group} of a \grammarterm{module-file}, -the program is ill-formed. +\begin{example} +The following defines a function-like +macro whose value is the maximum of its arguments. +It has the disadvantages of evaluating one or the other of its arguments +a second time +(including +\indextext{side effects}% +side effects) +and generating more code than a function if invoked several times. +It also cannot have its address taken, +as it has none. + +\begin{codeblock} +#define max(a, b) ((a) > (b) ? (a) : (b)) +\end{codeblock} + +The parentheses ensure that the arguments and +the resulting expression are bound properly. +\end{example} \pnum -In all three forms of \grammarterm{pp-import}, -the \tcode{import} and \tcode{export} (if it exists) preprocessing tokens -are replaced by the \grammarterm{import-keyword} and -\grammarterm{export-keyword} preprocessing tokens respectively. -\begin{note} -This makes the line no longer a directive -so it is not removed at the end of phase 4. -\end{note} -Additionally, in the second form of \grammarterm{pp-import}, -a \grammarterm{header-name} token is formed as if -the \grammarterm{header-name-tokens} -were the \grammarterm{pp-tokens} of a \tcode{\#include} directive. -The \grammarterm{header-name-tokens} are replaced by -the \grammarterm{header-name} token. -\begin{note} -This ensures that imports are treated consistently by -the preprocessor and later phases of translation. -\end{note} +\indextext{macro!function-like!arguments}% +If there is a \tcode{...} immediately preceding the \tcode{)} in the +function-like macro +definition, then the trailing arguments (if any), including any separating comma preprocessing +tokens, are merged to form a single item: the \defn{variable arguments}. The number of +arguments so combined is such that, following merger, the number of arguments is +either equal to or +one more than the number of parameters in the macro definition (excluding the +\tcode{...}). + +\rSec2[cpp.subst]{Argument substitution}% +\indextext{macro!argument substitution}% +\indextext{argument substitution|see{macro, argument substitution}}% + +\indextext{__va_opt__@\mname{VA_OPT}}% +\begin{bnf} +\nontermdef{va-opt-replacement}\br + \terminal{\mname{VA_OPT} (} \opt{pp-tokens} \terminal{)} +\end{bnf} \pnum -Each \tcode{\#define} directive encountered when preprocessing -each translation unit in a program results in a distinct -\defnx{macro definition}{macro!definition}. -\begin{note} -A predefined macro name\iref{cpp.predefined} -is not introduced by a \tcode{\#define} directive. -Implementations providing mechanisms to predefine additional macros -are encouraged to not treat them -as being introduced by a \tcode{\#define} directive. -\end{note} -Each macro definition has at most one point of definition in -each translation unit and at most one point of undefinition, as follows: -\begin{itemize} -\item -\indextext{point of!macro definition|see{macro, point of definition}}% -The \defnx{point of definition}{macro!point of definition} -of a macro definition within a translation unit $T$ is +After the arguments for the invocation of a function-like macro have +been identified, argument substitution takes place. +For each parameter in the replacement list that is neither +preceded by a \tcode{\#} or \tcode{\#\#} preprocessing token nor +followed by a \tcode{\#\#} preprocessing token, the preprocessing tokens +naming the parameter are replaced by a token sequence determined as follows: \begin{itemize} \item -if the \tcode{\#define} directive of the macro definition occurs within $T$, -the point at which that directive occurs, or otherwise, + If the parameter is of the form \grammarterm{va-opt-replacement}, + the replacement preprocessing tokens are the + preprocessing token sequence for the corresponding argument, + as specified below. \item -if the macro name is not lexically identical to a keyword\iref{lex.key} -or to the \grammarterm{identifier}{s} \tcode{module} or \tcode{import}, -the first point of macro import in $T$ of a header unit -containing a point of definition for the macro definition, if any. + Otherwise, the replacement preprocessing tokens are the + preprocessing tokens of corresponding argument after all + macros contained therein have been expanded. The argument's + preprocessing tokens are completely macro replaced before + being substituted as if they formed the rest of the preprocessing + file with no other preprocessing tokens being available. \end{itemize} -In the latter case, the macro is said -to be \defnx{imported}{macro!import} from the header unit. +\begin{example} +\begin{codeblock} +#define LPAREN() ( +#define G(Q) 42 +#define F(R, X, ...) __VA_OPT__(G R X) ) +int x = F(LPAREN(), 0, <:-); // replaced by \tcode{int x = 42;} +\end{codeblock} +\end{example} -\item -\indextext{point of!macro undefinition|see{macro, point of undefinition}}% -The \defnx{point of undefinition}{macro!point of undefinition} -of a macro definition within a translation unit -is the first point at which a \tcode{\#undef} directive naming the macro occurs -after its point of definition, or the first point -of macro import of a header unit containing a point of undefinition for the -macro definition, whichever (if any) occurs first. -\end{itemize} +\pnum +\indextext{__va_args__@\mname{VA_ARGS}}% +An identifier \mname{VA_ARGS} that occurs in the replacement list +shall be treated as if it were a parameter, and the variable arguments shall form +the preprocessing tokens used to replace it. \pnum -\indextext{active macro directive|see{macro, active}}% -A macro directive is \defnx{active}{macro!active} at a source location -if it has a point of definition in that translation unit preceding the location, -and does not have a point of undefinition in that translation unit preceding -the location. +\begin{example} +\begin{codeblock} +#define debug(...) fprintf(stderr, @\mname{VA_ARGS}@) +#define showlist(...) puts(#@\mname{VA_ARGS}@) +#define report(test, ...) ((test) ? puts(#test) : printf(@\mname{VA_ARGS}@)) +debug("Flag"); +debug("X = %d\n", x); +showlist(The first, second, and third items.); +report(x>y, "x is %d but y is %d", x, y); +\end{codeblock} +results in +\begin{codeblock} +fprintf(stderr, "Flag"); +fprintf(stderr, "X = %d\n", x); +puts("The first, second, and third items."); +((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y)); +\end{codeblock} +\end{example} \pnum -If a macro would be replaced or redefined, and multiple macro definitions -are active for that macro name, the active macro definitions shall all be -valid redefinitions of the same macro\iref{cpp.replace}. +\indextext{__va_opt__@\mname{VA_OPT}}% +The identifier \mname{VA_OPT} +shall always occur as part of the preprocessing token sequence +\grammarterm{va-opt-replacement}; +its closing \tcode{)} is determined by skipping +intervening pairs of matching left and right parentheses +in its \grammarterm{pp-tokens}. +The \grammarterm{pp-tokens} of a \grammarterm{va-opt-replacement} +shall not contain \mname{VA_OPT}. +If the \grammarterm{pp-tokens} would be ill-formed +as the replacement list of the current function-like macro, +the program is ill-formed. +A \grammarterm{va-opt-replacement} is treated as if it were a parameter, +and the preprocessing token sequence for the corresponding +argument is defined as follows. +If the substitution of \mname{VA_ARGS} as neither an operand +of \tcode{\#} nor \tcode{\#\#} consists of no preprocessing tokens, +the argument consists of +a single placemarker preprocessing token\iref{cpp.concat,cpp.rescan}. +Otherwise, the argument consists of +the results of the expansion of the contained \grammarterm{pp-tokens} +as the replacement list of the current function-like macro +before removal of placemarker tokens, rescanning, and further replacement. \begin{note} -The relative order of \grammarterm{pp-import}{s} has no bearing on whether a -particular macro definition is active. +The placemarker tokens are removed before stringization\iref{cpp.stringize}, +and can be removed by rescanning and further replacement\iref{cpp.rescan}. \end{note} - -\pnum \begin{example} -\begin{codeblocktu}{Importable header \tcode{"a.h"}} -#define X 123 // \#1 -#define Y 45 // \#2 -#define Z a // \#3 -#undef X // point of undefinition of \#1 in \tcode{"a.h"} -\end{codeblocktu} +\begin{codeblock} +#define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) +#define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) +#define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) +#define EMP -\begin{codeblocktu}{Importable header \tcode{"b.h"}} -import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"b.h"} -#define X 456 // OK, \#1 is not active -#define Y 6 // error: \#2 is active -\end{codeblocktu} +F(a, b, c) // replaced by \tcode{f(0, a, b, c)} +F() // replaced by \tcode{f(0)} +F(EMP) // replaced by \tcode{f(0)} -\begin{codeblocktu}{Importable header \tcode{"c.h"}} -#define Y 45 // \#4 -#define Z c // \#5 -\end{codeblocktu} +G(a, b, c) // replaced by \tcode{f(0, a, b, c)} +G(a, ) // replaced by \tcode{f(0, a)} +G(a) // replaced by \tcode{f(0, a)} -\begin{codeblocktu}{Importable header \tcode{"d.h"}} -import "c.h"; // point of definition of \#4 and \#5 in \tcode{"d.h"} -\end{codeblocktu} +SDEF(foo); // replaced by \tcode{S foo;} +SDEF(bar, 1, 2); // replaced by \tcode{S bar = \{ 1, 2 \};} -\begin{codeblocktu}{Importable header \tcode{"e.h"}} -import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"e.h"} -import "d.h"; // point of definition of \#4 and \#5 in \tcode{"e.h"} -int a = Y; // OK, active macro definitions \#2 and \#4 are valid redefinitions -int c = Z; // error: active macro definitions \#3 and \#5 are not valid redefinitions of \tcode{Z} -\end{codeblocktu} +#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: \tcode{\#\#} may not appear at + // the beginning of a replacement list\iref{cpp.concat} -\begin{codeblocktu}{Module unit \tcode{f}} -export module f; -export import "a.h"; +#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ +H2(a, b, c, d) // replaced by \tcode{ab, c, d} -int a = Y; // OK -\end{codeblocktu} +#define H3(X, ...) #__VA_OPT__(X##X X##X) +H3(, 0) // replaced by \tcode{""} -\begin{codeblocktu}{Translation unit \tcode{\#1}} -import f; -int x = Y; // error: \tcode{Y} is neither a defined macro nor a declared name -\end{codeblocktu} -\end{example} -\indextext{macro!import|)} +#define H4(X, ...) __VA_OPT__(a X ## X) ## b +H4(, 1) // replaced by \tcode{a b} -\rSec1[cpp.replace]{Macro replacement}% +#define H5A(...) __VA_OPT__()@\tcode{/**/}@__VA_OPT__() +#define H5B(X) a ## X ## b +#define H5C(X) H5B(X) +H5C(H5A()) // replaced by \tcode{ab} +\end{codeblock} +\end{example} -\rSec2[cpp.replace.general]{General}% -\indextext{macro!replacement|(}% -\indextext{replacement!macro|see{macro, replacement}}% -\indextext{preprocessing directive!macro replacement|see{macro, replacement}} +\rSec2[cpp.stringize]{The \tcode{\#} operator}% +\indextext{\#\#0 operator@\tcode{\#} operator}% +\indextext{stringize|see{\tcode{\#} operator}} \pnum -\indextext{macro!replacement list}% -Two replacement lists are identical if and only if -the preprocessing tokens in both have -the same number, ordering, spelling, and whitespace separation, -where all whitespace separations are considered identical. +Each +\tcode{\#} +preprocessing token in the replacement list for a function-like +macro shall be followed by a parameter as the next preprocessing +token in the replacement list. \pnum -An identifier currently defined as an -\indextext{macro!object-like}% -object-like macro (see below) may be redefined by another -\tcode{\#define} -preprocessing directive provided that the second definition is an -object-like macro definition and the two replacement lists -are identical, otherwise the program is ill-formed. -Likewise, an identifier currently defined as a -\indextext{macro!function-like}% -function-like macro (see below) may be redefined by another -\tcode{\#define} -preprocessing directive provided that the second definition is a -function-like macro definition that has the same number and spelling -of parameters, -and the two replacement lists are identical, -otherwise the program is ill-formed. +A \defn{character string literal} is a \grammarterm{string-literal} with no prefix. +If, in the replacement list, a parameter is immediately +preceded by a +\tcode{\#} +preprocessing token, +both are replaced by a single character string literal preprocessing token that +contains the spelling of the preprocessing token sequence for the +corresponding argument (excluding placemarker tokens). +Let the \defn{stringizing argument} be the preprocessing token sequence +for the corresponding argument with placemarker tokens removed. +Each occurrence of whitespace between the stringizing argument's preprocessing +tokens becomes a single space character in the character string literal. +Whitespace before the first preprocessing token and after the last +preprocessing token comprising the stringizing argument is deleted. +Otherwise, the original spelling of each preprocessing token in the +stringizing argument is retained in the character string literal, +except for special handling for producing the spelling of +\grammarterm{string-literal}s and \grammarterm{character-literal}s: +a +\tcode{\textbackslash} +character is inserted before each +\tcode{"} +and +\tcode{\textbackslash} +character of a \grammarterm{character-literal} or \grammarterm{string-literal} +(including the delimiting +\tcode{"} +characters). +If the replacement that results is not a valid character string literal, +the behavior is undefined. The character string literal corresponding to +an empty stringizing argument is \tcode{""}. +The order of evaluation of +\tcode{\#} +and +\tcode{\#\#} +operators is unspecified. -\pnum -\begin{example} -The following sequence is valid: -\begin{codeblock} -#define OBJ_LIKE (1-1) -#define OBJ_LIKE @\tcode{/* whitespace */ (1-1) /* other */}@ -#define FUNC_LIKE(a) ( a ) -#define FUNC_LIKE( a )( @\tcode{/* note the whitespace */ \textbackslash}@ - a @\tcode{/* other stuff on this line}@ - @\tcode{*/}@ ) -\end{codeblock} -But the following redefinitions are invalid: -\begin{codeblock} -#define OBJ_LIKE (0) // different token sequence -#define OBJ_LIKE (1 - 1) // different whitespace -#define FUNC_LIKE(b) ( a ) // different parameter usage -#define FUNC_LIKE(b) ( b ) // different parameter spelling -\end{codeblock} -\end{example} +\rSec2[cpp.concat]{The \tcode{\#\#} operator}% +\indextext{\#\#1 operator@\tcode{\#\#} operator}% +\indextext{concatenation!macro argument|see{\tcode{\#\#} operator}} \pnum -\indextext{macro!replacement list}% -There shall be whitespace between the identifier and the replacement list -in the definition of an object-like macro. +A +\tcode{\#\#} +preprocessing token shall not occur at the beginning or +at the end of a replacement list for either form +of macro definition. \pnum -If the \grammarterm{identifier-list} in the macro definition does not end with -an ellipsis, the number of arguments (including those arguments consisting -of no preprocessing tokens) -in an invocation of a function-like macro shall -equal the number of parameters in the macro definition. -Otherwise, there shall be at least as many arguments in the invocation as there are -parameters in the macro definition (excluding the \tcode{...}). There -shall exist a -\tcode{)} -preprocessing token that terminates the invocation. +If, in the replacement list of a function-like macro, a parameter is +immediately preceded or followed by a +\tcode{\#\#} +preprocessing token, the parameter is replaced by the +corresponding argument's preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is +replaced by a placemarker preprocessing token instead. +\begin{footnote} +Placemarker preprocessing tokens do not appear in the syntax +because they are temporary entities that exist only within translation phase 4. +\end{footnote} \pnum -\indextext{__va_args__@\mname{VA_ARGS}}% -\indextext{__va_opt__@\mname{VA_OPT}}% -The identifiers \mname{VA_ARGS} and \mname{VA_OPT} -shall occur only in the \grammarterm{replacement-list} -of a function-like macro that uses the ellipsis notation in the parameters. +For both object-like and function-like macro invocations, before the +replacement list is reexamined for more macro names to replace, +each instance of a +\tcode{\#\#} +preprocessing token in the replacement list +(not from an argument) is deleted and the +preceding preprocessing token is concatenated +with the following preprocessing token. +Placemarker preprocessing tokens are handled specially: concatenation +of two placemarkers results in a single placemarker preprocessing token, and +concatenation of a placemarker with a non-placemarker preprocessing token results +in the non-placemarker preprocessing token. +\begin{note} +Concatenation can form +a \grammarterm{universal-character-name}\iref{lex.charset}. +\end{note} +If the result is not a valid preprocessing token, +the behavior is undefined. +The resulting token is available for further macro replacement. +The order of evaluation of +\tcode{\#\#} +operators is unspecified. \pnum -A parameter identifier in a function-like macro -shall be uniquely declared within its scope. +\begin{example} +The sequence +\begin{codeblock} +#define str(s) # s +#define xstr(s) str(s) +#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", @\textbackslash@ + x ## s, x ## t) +#define INCFILE(n) vers ## n +#define glue(a, b) a ## b +#define xglue(a, b) glue(a, b) +#define HIGHLOW "hello" +#define LOW LOW ", world" -\pnum -The identifier immediately following the -\tcode{define} -is called the -\indextext{name!macro|see{macro, name}}% -\defnx{macro name}{macro!name}. -There is one name space for macro names. -Any whitespace characters preceding or following the -replacement list of preprocessing tokens are not considered -part of the replacement list for either form of macro. +debug(1, 2); +fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away + == 0) str(: @\atsign\textbackslash@n), s); +#include xstr(INCFILE(2).h) +glue(HIGH, LOW); +xglue(HIGH, LOW) +\end{codeblock} +results in +\begin{codeblock} +printf("x" "1" "= %d, x" "2" "= %s", x1, x2); +fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0" ": @\atsign\textbackslash@n", s); +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ +"hello"; +"hello" ", world" +\end{codeblock} +or, after concatenation of the character string literals, +\begin{codeblock} +printf("x1= %d, x2= %s", x1, x2); +fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0: @\atsign\textbackslash@n", s); +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ +"hello"; +"hello, world" +\end{codeblock} -\pnum -If a -\indextext{\#\#0 operator@\tcode{\#} operator} -\tcode{\#} -preprocessing token, -followed by an identifier, -occurs lexically -at the point at which a preprocessing directive can begin, -the identifier is not subject to macro replacement. +Space around the \tcode{\#} and \tcode{\#\#} tokens in the macro definition +is optional. +\end{example} \pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# define} identifier replacement-list new-line -\indextext{\idxcode{\#define}}% -\end{ncsimplebnf} -defines an -\defnadj{object-like}{macro} that -causes each subsequent instance of the macro name -\begin{footnote} -Since, by macro-replacement time, -all \grammarterm{character-literal}s and \grammarterm{string-literal}s are preprocessing tokens, -not sequences possibly containing identifier-like subsequences -(see \ref{lex.phases}, translation phases), -they are never scanned for macro names or parameters. -\end{footnote} -to be replaced by the replacement list of preprocessing tokens -that constitute the remainder of the directive. -\begin{footnote} -An alternative token\iref{lex.digraph} is not an identifier, -even when its spelling consists entirely of letters and underscores. -Therefore it is not possible to define a macro -whose name is the same as that of an alternative token. -\end{footnote} -The replacement list is then rescanned for more macro names as -specified below. +\begin{example} +In the following fragment: + +\begin{codeblock} +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) +char p[] = join(x, y); // equivalent to \tcode{char p[] = "x \#\# y";} +\end{codeblock} + +The expansion produces, at various stages: + +\begin{codeblock} +join(x, y) +in_between(x hash_hash y) +in_between(x ## y) +mkstr(x ## y) +"x ## y" +\end{codeblock} + +In other words, expanding \tcode{hash_hash} produces a new token, +consisting of two adjacent sharp signs, but this new token is not the +\tcode{\#\#} operator. +\end{example} \pnum \begin{example} -The simplest use of this facility is to define a ``manifest constant'', -as in +To illustrate the rules for placemarker preprocessing tokens, the sequence \begin{codeblock} -#define TABSIZE 100 -int table[TABSIZE]; +#define t(x,y,z) x ## y ## z +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), + t(10,,), t(,11,), t(,,12), t(,,) }; +\end{codeblock} +results in +\begin{codeblock} +int j[] = { 123, 45, 67, 89, + 10, 11, 12, }; \end{codeblock} \end{example} -\pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# define} identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br -\terminal{\# define} identifier lparen \terminal{...} \terminal{)} replacement-list new-line\br -\terminal{\# define} identifier lparen identifier-list \terminal{, ...} \terminal{)} replacement-list new-line -\end{ncsimplebnf} -defines a \defnadj{function-like}{macro} -with parameters, whose use is -similar syntactically to a function call. -The parameters -\indextext{parameter!macro}% -are specified by the optional list of identifiers. -Each subsequent instance of the function-like macro name followed by a -\tcode{(} -as the next preprocessing token -introduces the sequence of preprocessing tokens that is replaced -by the replacement list in the definition -(an invocation of the macro). -\indextext{invocation!macro}% -The replaced sequence of preprocessing tokens is terminated by the matching -\tcode{)} -preprocessing token, skipping intervening matched pairs of left and -right parenthesis preprocessing tokens. -Within the sequence of preprocessing tokens making up an invocation -of a function-like macro, -new-line is considered a normal whitespace character. +\rSec2[cpp.rescan]{Rescanning and further replacement}% +\indextext{macro!rescanning and replacement}% +\indextext{rescanning and replacement|see{macro, rescanning and replacement}} \pnum -\indextext{macro!function-like!arguments}% -The sequence of preprocessing tokens -bounded by the outside-most matching parentheses -forms the list of arguments for the function-like macro. -The individual arguments within the list -are separated by comma preprocessing tokens, -but comma preprocessing tokens between matching -inner parentheses do not separate arguments. -If there are sequences of preprocessing tokens within the list of -arguments that would otherwise act as preprocessing directives, -\begin{footnote} -A \grammarterm{conditionally-supported-directive} is a preprocessing directive regardless of whether the implementation supports it. -\end{footnote} -the behavior is undefined. +After all parameters in the replacement list have been substituted and \tcode{\#} and \tcode{\#\#} processing has taken +place, all placemarker preprocessing tokens are removed. Then +the resulting preprocessing token sequence is rescanned, along with all +subsequent preprocessing tokens of the source file, for more macro names +to replace. \pnum \begin{example} -The following defines a function-like -macro whose value is the maximum of its arguments. -It has the disadvantages of evaluating one or the other of its arguments -a second time -(including -\indextext{side effects}% -side effects) -and generating more code than a function if invoked several times. -It also cannot have its address taken, -as it has none. +The sequence +\begin{codeblock} +#define x 3 +#define f(a) f(x * (a)) +#undef x +#define x 2 +#define g f +#define z z[0] +#define h g(~ +#define m(a) a(w) +#define w 0,1 +#define t(a) a +#define p() int +#define q(x) x +#define r(x,y) x ## y +#define str(x) # x +f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); +g(x+(3,4)-w) | h 5) & m + (f)^m(m); +p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; +char c[2][6] = { str(hello), str() }; +\end{codeblock} +results in \begin{codeblock} -#define max(a, b) ((a) > (b) ? (a) : (b)) +f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); +f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); +int i[] = { 1, 23, 4, 5, }; +char c[2][6] = { "hello", "" }; \end{codeblock} - -The parentheses ensure that the arguments and -the resulting expression are bound properly. \end{example} \pnum -\indextext{macro!function-like!arguments}% -If there is a \tcode{...} immediately preceding the \tcode{)} in the -function-like macro -definition, then the trailing arguments (if any), including any separating comma preprocessing -tokens, are merged to form a single item: the \defn{variable arguments}. The number of -arguments so combined is such that, following merger, the number of arguments is -either equal to or -one more than the number of parameters in the macro definition (excluding the -\tcode{...}). +If the name of the macro being replaced is found during this scan of +the replacement list +(not including the rest of the source file's preprocessing tokens), +it is not replaced. +Furthermore, +if any nested replacements encounter the name of the macro being replaced, +it is not replaced. +These nonreplaced macro name preprocessing tokens are no longer available +for further replacement even if they are later (re)examined in contexts +in which that macro name preprocessing token would otherwise have been +replaced. -\rSec2[cpp.subst]{Argument substitution}% -\indextext{macro!argument substitution}% -\indextext{argument substitution|see{macro, argument substitution}}% +\pnum +The resulting completely macro-replaced preprocessing token sequence +is not processed as a preprocessing directive even if it resembles one, +but all pragma unary operator expressions within it are then processed as +specified in~\ref{cpp.pragma.op} below. -\indextext{__va_opt__@\mname{VA_OPT}}% -\begin{bnf} -\nontermdef{va-opt-replacement}\br - \terminal{\mname{VA_OPT} (} \opt{pp-tokens} \terminal{)} -\end{bnf} +\rSec2[cpp.scope]{Scope of macro definitions}% +\indextext{macro!scope of definition}% +\indextext{scope!macro definition|see{macro, scope of definition}} \pnum -After the arguments for the invocation of a function-like macro have -been identified, argument substitution takes place. -For each parameter in the replacement list that is neither -preceded by a \tcode{\#} or \tcode{\#\#} preprocessing token nor -followed by a \tcode{\#\#} preprocessing token, the preprocessing tokens -naming the parameter are replaced by a token sequence determined as follows: -\begin{itemize} -\item - If the parameter is of the form \grammarterm{va-opt-replacement}, - the replacement preprocessing tokens are the - preprocessing token sequence for the corresponding argument, - as specified below. -\item - Otherwise, the replacement preprocessing tokens are the - preprocessing tokens of corresponding argument after all - macros contained therein have been expanded. The argument's - preprocessing tokens are completely macro replaced before - being substituted as if they formed the rest of the preprocessing - file with no other preprocessing tokens being available. -\end{itemize} -\begin{example} -\begin{codeblock} -#define LPAREN() ( -#define G(Q) 42 -#define F(R, X, ...) __VA_OPT__(G R X) ) -int x = F(LPAREN(), 0, <:-); // replaced by \tcode{int x = 42;} -\end{codeblock} -\end{example} +A macro definition lasts +(independent of block structure) +until a corresponding +\tcode{\#undef} +directive is encountered or +(if none is encountered) +until the end of the translation unit. +Macro definitions have no significance after translation phase 4. \pnum -\indextext{__va_args__@\mname{VA_ARGS}}% -An identifier \mname{VA_ARGS} that occurs in the replacement list -shall be treated as if it were a parameter, and the variable arguments shall form -the preprocessing tokens used to replace it. +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# undef} identifier new-line +\indextext{\idxcode{\#undef}}% +\end{ncsimplebnf} +causes the specified identifier no longer to be defined as a macro name. +It is ignored if the specified identifier is not currently defined as +a macro name. -\pnum -\begin{example} -\begin{codeblock} -#define debug(...) fprintf(stderr, @\mname{VA_ARGS}@) -#define showlist(...) puts(#@\mname{VA_ARGS}@) -#define report(test, ...) ((test) ? puts(#test) : printf(@\mname{VA_ARGS}@)) -debug("Flag"); -debug("X = %d\n", x); -showlist(The first, second, and third items.); -report(x>y, "x is %d but y is %d", x, y); -\end{codeblock} -results in -\begin{codeblock} -fprintf(stderr, "Flag"); -fprintf(stderr, "X = %d\n", x); -puts("The first, second, and third items."); -((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y)); -\end{codeblock} -\end{example} +\indextext{macro!replacement|)} + +\rSec1[cpp.predefined]{Predefined macro names} +\indextext{macro!predefined}% +\indextext{name!predefined macro|see{macro, predefined}} \pnum -\indextext{__va_opt__@\mname{VA_OPT}}% -The identifier \mname{VA_OPT} -shall always occur as part of the preprocessing token sequence -\grammarterm{va-opt-replacement}; -its closing \tcode{)} is determined by skipping -intervening pairs of matching left and right parentheses -in its \grammarterm{pp-tokens}. -The \grammarterm{pp-tokens} of a \grammarterm{va-opt-replacement} -shall not contain \mname{VA_OPT}. -If the \grammarterm{pp-tokens} would be ill-formed -as the replacement list of the current function-like macro, -the program is ill-formed. -A \grammarterm{va-opt-replacement} is treated as if it were a parameter, -and the preprocessing token sequence for the corresponding -argument is defined as follows. -If the substitution of \mname{VA_ARGS} as neither an operand -of \tcode{\#} nor \tcode{\#\#} consists of no preprocessing tokens, -the argument consists of -a single placemarker preprocessing token\iref{cpp.concat,cpp.rescan}. -Otherwise, the argument consists of -the results of the expansion of the contained \grammarterm{pp-tokens} -as the replacement list of the current function-like macro -before removal of placemarker tokens, rescanning, and further replacement. +The following macro names shall be defined by the implementation: + +\begin{description} + +\item +\indextext{\idxxname{cplusplus}}% +\xname{cplusplus}\\ +The integer literal \tcode{\cppver}. \begin{note} -The placemarker tokens are removed before stringization\iref{cpp.stringize}, -and can be removed by rescanning and further replacement\iref{cpp.rescan}. +Future revisions of this document will +replace the value of this macro with a greater value. \end{note} -\begin{example} -\begin{codeblock} -#define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) -#define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) -#define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) -#define EMP -F(a, b, c) // replaced by \tcode{f(0, a, b, c)} -F() // replaced by \tcode{f(0)} -F(EMP) // replaced by \tcode{f(0)} +\item The names listed in \tref{cpp.predefined.ft}.\\ +The macros defined in \tref{cpp.predefined.ft} shall be defined to +the corresponding integer literal. +\begin{note} +Future revisions of this document might replace +the values of these macros with greater values. +\end{note} -G(a, b, c) // replaced by \tcode{f(0, a, b, c)} -G(a, ) // replaced by \tcode{f(0, a)} -G(a) // replaced by \tcode{f(0, a)} +\item +\indextext{__date__@\mname{DATE}}% +\mname{DATE}\\ +The date of translation of the source file: +a character string literal of the form +\tcode{"Mmm~dd~yyyy"}, +where the names of the months are the same as those generated +by the +\tcode{asctime} +function, +and the first character of +\tcode{dd} +is a space character if the value is less than 10. +If the date of translation is not available, +an \impldef{text of \mname{DATE} when date of translation is not available} valid date +shall be supplied. -SDEF(foo); // replaced by \tcode{S foo;} -SDEF(bar, 1, 2); // replaced by \tcode{S bar = \{ 1, 2 \};} +\item +\indextext{__file__@\mname{FILE}}% +\mname{FILE}\\ +The presumed name of the current source file (a character string +literal). +\begin{footnote} +The presumed source file name can be changed by the \tcode{\#line} directive. +\end{footnote} -#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: \tcode{\#\#} may not appear at - // the beginning of a replacement list\iref{cpp.concat} +\item +\indextext{__line__@\mname{LINE}}% +\mname{LINE}\\ +The presumed line number (within the current source file) of the current source line +(an integer literal). +\begin{footnote} +The presumed line number can be changed by the \tcode{\#line} directive. +\end{footnote} -#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ -H2(a, b, c, d) // replaced by \tcode{ab, c, d} +\item +\indextext{__stdc_hosted__@\mname{STDC_HOSTED}}% +\indextext{implementation!hosted}% +\indextext{implementation!freestanding}% +\mname{STDC_HOSTED}\\ +The integer literal \tcode{1} +if the implementation is a hosted implementation or +the integer literal \tcode{0} +if it is a freestanding implementation\iref{intro.compliance}. -#define H3(X, ...) #__VA_OPT__(X##X X##X) -H3(, 0) // replaced by \tcode{""} +\item +\indextext{__stdcpp_default_new_alignment__@\mname{STDCPP_DEFAULT_NEW_ALIGNMENT}}% +\mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\\ +An integer literal of type \tcode{std::size_t} +whose value is the alignment guaranteed +by a call to \tcode{operator new(std::size_t)} +or \tcode{operator new[](std::size_t)}. +\begin{note} +Larger alignments will be passed to +\tcode{operator new(std::size_t, std::align_val_t)}, etc.\iref{expr.new}. +\end{note} -#define H4(X, ...) __VA_OPT__(a X ## X) ## b -H4(, 1) // replaced by \tcode{a b} +\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}. -#define H5A(...) __VA_OPT__()@\tcode{/**/}@__VA_OPT__() -#define H5B(X) a ## X ## b -#define H5C(X) H5B(X) -H5C(H5A()) // replaced by \tcode{ab} -\end{codeblock} -\end{example} +\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. -\rSec2[cpp.stringize]{The \tcode{\#} operator}% -\indextext{\#\#0 operator@\tcode{\#} operator}% -\indextext{stringize|see{\tcode{\#} operator}} +\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. -\pnum -Each -\tcode{\#} -preprocessing token in the replacement list for a function-like -macro shall be followed by a parameter as the next preprocessing -token in the replacement list. +\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. -\pnum -A \defn{character string literal} is a \grammarterm{string-literal} with no prefix. -If, in the replacement list, a parameter is immediately -preceded by a -\tcode{\#} -preprocessing token, -both are replaced by a single character string literal preprocessing token that -contains the spelling of the preprocessing token sequence for the -corresponding argument (excluding placemarker tokens). -Let the \defn{stringizing argument} be the preprocessing token sequence -for the corresponding argument with placemarker tokens removed. -Each occurrence of whitespace between the stringizing argument's preprocessing -tokens becomes a single space character in the character string literal. -Whitespace before the first preprocessing token and after the last -preprocessing token comprising the stringizing argument is deleted. -Otherwise, the original spelling of each preprocessing token in the -stringizing argument is retained in the character string literal, -except for special handling for producing the spelling of -\grammarterm{string-literal}s and \grammarterm{character-literal}s: -a -\tcode{\textbackslash} -character is inserted before each -\tcode{"} -and -\tcode{\textbackslash} -character of a \grammarterm{character-literal} or \grammarterm{string-literal} -(including the delimiting -\tcode{"} -characters). -If the replacement that results is not a valid character string literal, -the behavior is undefined. The character string literal corresponding to -an empty stringizing argument is \tcode{""}. -The order of evaluation of -\tcode{\#} -and -\tcode{\#\#} -operators is unspecified. +\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}. -\rSec2[cpp.concat]{The \tcode{\#\#} operator}% -\indextext{\#\#1 operator@\tcode{\#\#} operator}% -\indextext{concatenation!macro argument|see{\tcode{\#\#} operator}} +\item +\indextext{__time__@\mname{TIME}}% +\mname{TIME}\\ +The time of translation of the source file: +a character string literal of the form +\tcode{"hh:mm:ss"} +as in the time generated by the +\tcode{asctime} +function. +If the time of translation is not available, +an \impldef{text of \mname{TIME} when time of translation is not available} valid time shall be supplied. +\end{description} + +\indextext{macro!feature-test}% +\indextext{feature-test macro|see{macro, feature-test}}% +\begin{LongTable}{Feature-test macros}{cpp.predefined.ft}{ll} +\\ \topline +\lhdr{Macro name} & \rhdr{Value} \\ \capsep +\endfirsthead +\continuedcaption \\ +\hline +\lhdr{Name} & \rhdr{Value} \\ \capsep +\endhead +\defnxname{cpp_aggregate_bases} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_aggregate_nsdmi} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_aggregate_paren_init} & \tcode{201902L} \\ \rowsep +\defnxname{cpp_alias_templates} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_aligned_new} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_auto_cast} & \tcode{202110L} \\ \rowsep +\defnxname{cpp_binary_literals} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_capture_star_this} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_char8_t} & \tcode{202207L} \\ \rowsep +\defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep +\defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep +\defnxname{cpp_constexpr} & \tcode{202406L} \\ \rowsep +\defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep +\defnxname{cpp_consteval} & \tcode{202211L} \\ \rowsep +\defnxname{cpp_constinit} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep +\defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_deduction_guides} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_delegating_constructors} & \tcode{200604L} \\ \rowsep +\defnxname{cpp_deleted_function} & \tcode{202403L} \\ \rowsep +\defnxname{cpp_designated_initializers} & \tcode{201707L} \\ \rowsep +\defnxname{cpp_enumerator_attributes} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_explicit_this_parameter} & \tcode{202110L} \\ \rowsep +\defnxname{cpp_fold_expressions} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_generic_lambdas} & \tcode{201707L} \\ \rowsep +\defnxname{cpp_guaranteed_copy_elision} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_hex_float} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_if_consteval} & \tcode{202106L} \\ \rowsep +\defnxname{cpp_if_constexpr} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_impl_coroutine} & \tcode{201902L} \\ \rowsep +\defnxname{cpp_impl_destroying_delete} & \tcode{201806L} \\ \rowsep +\defnxname{cpp_impl_three_way_comparison} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_implicit_move} & \tcode{202207L} \\ \rowsep +\defnxname{cpp_inheriting_constructors} & \tcode{201511L} \\ \rowsep +\defnxname{cpp_init_captures} & \tcode{201803L} \\ \rowsep +\defnxname{cpp_initializer_lists} & \tcode{200806L} \\ \rowsep +\defnxname{cpp_inline_variables} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_lambdas} & \tcode{200907L} \\ \rowsep +\defnxname{cpp_modules} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_multidimensional_subscript} & \tcode{202211L} \\ \rowsep +\defnxname{cpp_named_character_escapes} & \tcode{202207L} \\ \rowsep +\defnxname{cpp_namespace_attributes} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_noexcept_function_type} & \tcode{201510L} \\ \rowsep +\defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep +\defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep +\defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep +\defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep +\defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_ref_qualifiers} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_return_type_deduction} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_rvalue_references} & \tcode{200610L} \\ \rowsep +\defnxname{cpp_size_t_suffix} & \tcode{202011L} \\ \rowsep +\defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep +\defnxname{cpp_static_assert} & \tcode{202306L} \\ \rowsep +\defnxname{cpp_static_call_operator} & \tcode{202207L} \\ \rowsep +\defnxname{cpp_structured_bindings} & \tcode{202403L} \\ \rowsep +\defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep +\defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep +\defnxname{cpp_unicode_characters} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_using_enum} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_variable_templates} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_variadic_friend} & \tcode{202403L} \\ \rowsep +\defnxname{cpp_variadic_templates} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_variadic_using} & \tcode{201611L} \\ +\end{LongTable} \pnum -A -\tcode{\#\#} -preprocessing token shall not occur at the beginning or -at the end of a replacement list for either form -of macro definition. +The following macro names are conditionally defined by the implementation: + +\begin{description} +\item +\indextext{__stdc__@\mname{STDC}}% +\mname{STDC}\\ +Whether \mname{STDC} is predefined and if so, what its value is, +are \impldef{definition and meaning of \mname{STDC}}. + +\item +\indextext{__stdc_mb_might_neq_wc__@\mname{STDC_MB_MIGHT_NEQ_WC}}% +\mname{STDC_MB_MIGHT_NEQ_WC}\\ +The integer literal \tcode{1}, intended to indicate that, in the encoding for +\keyword{wchar_t}, a member of the basic character set need not have a code value equal to +its value when used as the lone character in an ordinary character literal. + +\item +\indextext{__stdc_version__@\mname{STDC_VERSION}}% +\mname{STDC_VERSION}\\ +Whether \mname{STDC_VERSION} is predefined and if so, what its value is, +are \impldef{definition and meaning of \mname{STDC_VERSION}}. + +\item +\indextext{__stdc_iso_10646__@\mname{STDC_ISO_10646}}% +\mname{STDC_ISO_10646}\\ +An integer literal of the form \tcode{yyyymmL} +(for example, \tcode{199712L}). +Whether \mname{STDC_ISO_10646} is predefined and +if so, what its value is, +are \impldef{presence and value of \mname{STDC_ISO_10646}}. + +\item +\indextext{__stdcpp_threads__@\mname{STDCPP_THREADS}}% +\mname{STDCPP_THREADS}\\ +Defined, and has the value integer literal 1, if and only if a program +can have more than one thread of execution\iref{intro.multithread}. + +\end{description} \pnum -If, in the replacement list of a function-like macro, a parameter is -immediately preceded or followed by a -\tcode{\#\#} -preprocessing token, the parameter is replaced by the -corresponding argument's preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is -replaced by a placemarker preprocessing token instead. -\begin{footnote} -Placemarker preprocessing tokens do not appear in the syntax -because they are temporary entities that exist only within translation phase 4. -\end{footnote} +The values of the predefined macros +(except for +\mname{FILE} +and +\mname{LINE}) +remain constant throughout the translation unit. \pnum -For both object-like and function-like macro invocations, before the -replacement list is reexamined for more macro names to replace, -each instance of a -\tcode{\#\#} -preprocessing token in the replacement list -(not from an argument) is deleted and the -preceding preprocessing token is concatenated -with the following preprocessing token. -Placemarker preprocessing tokens are handled specially: concatenation -of two placemarkers results in a single placemarker preprocessing token, and -concatenation of a placemarker with a non-placemarker preprocessing token results -in the non-placemarker preprocessing token. -\begin{note} -Concatenation can form -a \grammarterm{universal-character-name}\iref{lex.charset}. -\end{note} -If the result is not a valid preprocessing token, +If any of the pre-defined macro names in this subclause, +or the identifier +\tcode{defined}, +is the subject of a +\tcode{\#define} +or a +\tcode{\#undef} +preprocessing directive, the behavior is undefined. -The resulting token is available for further macro replacement. -The order of evaluation of -\tcode{\#\#} -operators is unspecified. +Any other predefined macro names shall begin with a +leading underscore followed by an uppercase letter or a second +underscore. -\pnum -\begin{example} -The sequence -\begin{codeblock} -#define str(s) # s -#define xstr(s) str(s) -#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", @\textbackslash@ - x ## s, x ## t) -#define INCFILE(n) vers ## n -#define glue(a, b) a ## b -#define xglue(a, b) glue(a, b) -#define HIGHLOW "hello" -#define LOW LOW ", world" +\rSec1[cpp.cond]{Conditional inclusion}% +\indextext{preprocessing directive!conditional inclusion}% +\indextext{inclusion!conditional|see{preprocessing directive, conditional inclusion}} -debug(1, 2); -fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away - == 0) str(: @\atsign\textbackslash@n), s); -#include xstr(INCFILE(2).h) -glue(HIGH, LOW); -xglue(HIGH, LOW) -\end{codeblock} -results in -\begin{codeblock} -printf("x" "1" "= %d, x" "2" "= %s", x1, x2); -fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0" ": @\atsign\textbackslash@n", s); -#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ -"hello"; -"hello" ", world" -\end{codeblock} -or, after concatenation of the character string literals, -\begin{codeblock} -printf("x1= %d, x2= %s", x1, x2); -fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0: @\atsign\textbackslash@n", s); -#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ -"hello"; -"hello, world" -\end{codeblock} - -Space around the \tcode{\#} and \tcode{\#\#} tokens in the macro definition -is optional. -\end{example} +\indextext{\idxcode{defined}}% +\begin{bnf} +\nontermdef{defined-macro-expression}\br + \terminal{defined} identifier\br + \terminal{defined (} identifier \terminal{)} +\end{bnf} -\pnum -\begin{example} -In the following fragment: +\begin{bnf} +\nontermdef{h-preprocessing-token}\br + \textnormal{any \grammarterm{preprocessing-token} other than \terminal{>}} +\end{bnf} -\begin{codeblock} -#define hash_hash # ## # -#define mkstr(a) # a -#define in_between(a) mkstr(a) -#define join(c, d) in_between(c hash_hash d) -char p[] = join(x, y); // equivalent to \tcode{char p[] = "x \#\# y";} -\end{codeblock} +\begin{bnf} +\nontermdef{h-pp-tokens}\br + h-preprocessing-token\br + h-pp-tokens h-preprocessing-token +\end{bnf} -The expansion produces, at various stages: +\begin{bnf} +\nontermdef{header-name-tokens}\br + string-literal\br + \terminal{<} h-pp-tokens \terminal{>} +\end{bnf} -\begin{codeblock} -join(x, y) -in_between(x hash_hash y) -in_between(x ## y) -mkstr(x ## y) -"x ## y" -\end{codeblock} +\indextext{\idxxname{has_include}}% +\begin{bnf} +\nontermdef{has-include-expression}\br + \terminal{\xname{has_include}} \terminal{(} header-name \terminal{)}\br + \terminal{\xname{has_include}} \terminal{(} header-name-tokens \terminal{)} +\end{bnf} -In other words, expanding \tcode{hash_hash} produces a new token, -consisting of two adjacent sharp signs, but this new token is not the -\tcode{\#\#} operator. -\end{example} +\indextext{\idxxname{has_cpp_attribute}}% +\begin{bnf} +\nontermdef{has-attribute-expression}\br + \terminal{\xname{has_cpp_attribute} (} pp-tokens \terminal{)} +\end{bnf} \pnum -\begin{example} -To illustrate the rules for placemarker preprocessing tokens, the sequence -\begin{codeblock} -#define t(x,y,z) x ## y ## z -int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), - t(10,,), t(,11,), t(,,12), t(,,) }; -\end{codeblock} -results in -\begin{codeblock} -int j[] = { 123, 45, 67, 89, - 10, 11, 12, }; -\end{codeblock} -\end{example} - -\rSec2[cpp.rescan]{Rescanning and further replacement}% -\indextext{macro!rescanning and replacement}% -\indextext{rescanning and replacement|see{macro, rescanning and replacement}} +The expression that controls conditional inclusion +shall be an integral constant expression except that +identifiers +(including those lexically identical to keywords) +are interpreted as described below +\begin{footnote} +Because the controlling constant expression is evaluated +during translation phase 4, +all identifiers either are or are not macro names --- +there simply are no keywords, enumeration constants, etc. +\end{footnote} +and it may contain zero or more \grammarterm{defined-macro-expression}{s} and/or +\grammarterm{has-include-expression}{s} and/or +\grammarterm{has-attribute-expression}{s} as unary operator expressions. \pnum -After all parameters in the replacement list have been substituted and \tcode{\#} and \tcode{\#\#} processing has taken -place, all placemarker preprocessing tokens are removed. Then -the resulting preprocessing token sequence is rescanned, along with all -subsequent preprocessing tokens of the source file, for more macro names -to replace. +A \grammarterm{defined-macro-expression} evaluates to \tcode{1} +if the identifier is currently defined +as a macro name +(that is, if it is predefined +or if it has one or more active macro definitions\iref{cpp.import}, +for example because +it has been the subject of a +\tcode{\#define} +preprocessing directive +without an intervening +\tcode{\#undef} +directive with the same subject identifier), \tcode{0} if it is not. \pnum -\begin{example} -The sequence -\begin{codeblock} -#define x 3 -#define f(a) f(x * (a)) -#undef x -#define x 2 -#define g f -#define z z[0] -#define h g(~ -#define m(a) a(w) -#define w 0,1 -#define t(a) a -#define p() int -#define q(x) x -#define r(x,y) x ## y -#define str(x) # x +The second form of \grammarterm{has-include-expression} +is considered only if the first form does not match, +in which case the preprocessing tokens are processed just as in normal text. -f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); -g(x+(3,4)-w) | h 5) & m - (f)^m(m); -p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; -char c[2][6] = { str(hello), str() }; -\end{codeblock} -results in -\begin{codeblock} -f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); -f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); -int i[] = { 1, 23, 4, 5, }; -char c[2][6] = { "hello", "" }; -\end{codeblock} -\end{example} +\pnum +The header or source file identified by +the parenthesized preprocessing token sequence +in each contained \grammarterm{has-include-expression} +is searched for as if that preprocessing token sequence +were the \grammarterm{pp-tokens} in a \tcode{\#include} directive, +except that no further macro expansion is performed. +If such a directive would not satisfy the syntactic requirements +of a \tcode{\#include} directive, the program is ill-formed. +The \grammarterm{has-include-expression} evaluates +to \tcode{1} if the search for the source file succeeds, and +to \tcode{0} if the search fails. \pnum -If the name of the macro being replaced is found during this scan of -the replacement list -(not including the rest of the source file's preprocessing tokens), -it is not replaced. -Furthermore, -if any nested replacements encounter the name of the macro being replaced, -it is not replaced. -These nonreplaced macro name preprocessing tokens are no longer available -for further replacement even if they are later (re)examined in contexts -in which that macro name preprocessing token would otherwise have been -replaced. +Each \grammarterm{has-attribute-expression} is replaced by +a non-zero \grammarterm{pp-number} +matching the form of an \grammarterm{integer-literal} +if the implementation supports an attribute +with the name specified by interpreting +the \grammarterm{pp-tokens}, after macro expansion, +as an \grammarterm{attribute-token}, +and by \tcode{0} otherwise. +The program is ill-formed if the \grammarterm{pp-tokens} +do not match the form of an \grammarterm{attribute-token}. \pnum -The resulting completely macro-replaced preprocessing token sequence -is not processed as a preprocessing directive even if it resembles one, -but all pragma unary operator expressions within it are then processed as -specified in~\ref{cpp.pragma.op} below. +For an attribute specified in this document, +it is \impldef{value of \grammarterm{has-attribute-expression} +for standard attributes} +whether the value of the \grammarterm{has-attribute-expression} +is \tcode{0} or is given by \tref{cpp.cond.ha}. +For other attributes recognized by the implementation, +the value is +\impldef{value of \grammarterm{has-attribute-expression} +for non-standard attributes}. +\begin{note} +It is expected +that the availability of an attribute can be detected by any non-zero result. +\end{note} -\rSec2[cpp.scope]{Scope of macro definitions}% -\indextext{macro!scope of definition}% -\indextext{scope!macro definition|see{macro, scope of definition}} +\begin{floattable}{\xname{has_cpp_attribute} values}{cpp.cond.ha} +{ll} +\topline +\lhdr{Attribute} & \rhdr{Value} \\ \rowsep +\tcode{assume} & \tcode{202207L} \\ +\tcode{carries_dependency} & \tcode{200809L} \\ +\tcode{deprecated} & \tcode{201309L} \\ +\tcode{fallthrough} & \tcode{201603L} \\ +\tcode{likely} & \tcode{201803L} \\ +\tcode{maybe_unused} & \tcode{201603L} \\ +\tcode{no_unique_address} & \tcode{201803L} \\ +\tcode{nodiscard} & \tcode{201907L} \\ +\tcode{noreturn} & \tcode{200809L} \\ +\tcode{unlikely} & \tcode{201803L} \\ +\end{floattable} \pnum -A macro definition lasts -(independent of block structure) -until a corresponding -\tcode{\#undef} -directive is encountered or -(if none is encountered) -until the end of the translation unit. -Macro definitions have no significance after translation phase 4. +The +\tcode{\#ifdef}, \tcode{\#ifndef}, \tcode{\#elifdef}, and \tcode{\#elifndef} +directives, and +the \tcode{defined} conditional inclusion operator, +shall treat \xname{has_include} and \xname{has_cpp_attribute} +as if they were the names of defined macros. +The identifiers \xname{has_include} and \xname{has_cpp_attribute} +shall not appear in any context not mentioned in this subclause. \pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# undef} identifier new-line -\indextext{\idxcode{\#undef}}% -\end{ncsimplebnf} -causes the specified identifier no longer to be defined as a macro name. -It is ignored if the specified identifier is not currently defined as -a macro name. - -\indextext{macro!replacement|)} - -\rSec1[cpp.line]{Line control}% -\indextext{preprocessing directive!line control}% -\indextext{\idxcode{\#line}|see{preprocessing directive, line control}} - -\pnum -The \grammarterm{string-literal} of a -\tcode{\#line} -directive, if present, -shall be a character string literal. - -\pnum -The -\defn{line number} -of the current source line is one greater than -the number of new-line characters read or introduced -in translation phase 1\iref{lex.phases} -while processing the source file to the current token. - -\pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# line} digit-sequence new-line -\end{ncsimplebnf} -causes the implementation to behave as if -the following sequence of source lines begins with a -source line that has a line number as specified -by the digit sequence (interpreted as a decimal integer). -If the digit sequence specifies zero -or a number greater than 2147483647, -the behavior is undefined. - -\pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# line} digit-sequence \terminal{"} \opt{s-char-sequence} \terminal{"} new-line -\end{ncsimplebnf} -sets the presumed line number similarly and changes the -presumed name of the source file to be the contents -of the character string literal. - -\pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# line} pp-tokens new-line -\end{ncsimplebnf} -(that does not match one of the two previous forms) -is permitted. -The preprocessing tokens after -\tcode{line} -on the directive are processed just as in normal text -(each identifier currently defined as a macro name is replaced by its -replacement list of preprocessing tokens). -If the directive resulting after all replacements does not match -one of the two previous forms, the behavior is undefined; -otherwise, the result is processed as appropriate. - -\rSec1[cpp.error]{Diagnostic directives}% -\indextext{preprocessing directive!error}% -\indextext{preprocessing directive!diagnostic}% -\indextext{preprocessing directive!warning}% -\indextext{\idxcode{\#error}|see{preprocessing directive, error}} - -\pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# error} \opt{pp-tokens} new-line -\end{ncsimplebnf} -renders the program ill-formed. -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# warning} \opt{pp-tokens} new-line -\end{ncsimplebnf} -requires the implementation to produce at least one diagnostic message -for the preprocessing translation unit\iref{intro.compliance.general}. -\recommended -Any diagnostic message caused by either of these directives -should include the specified sequence of preprocessing tokens. - -\rSec1[cpp.pragma]{Pragma directive}% -\indextext{preprocessing directive!pragma}% -\indextext{\idxcode{\#pragma}|see{preprocessing directive, pragma}} +Each preprocessing token that remains (in the list of preprocessing tokens that +will become the controlling expression) +after all macro replacements have occurred +shall be in the lexical form of a token\iref{lex.token}. \pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\# pragma} \opt{pp-tokens} new-line +Preprocessing directives of the forms +\begin{ncsimplebnf}\obeyspaces +\indextext{\idxcode{\#if}}% +\terminal{\# if } constant-expression new-line \opt{group}\br +\indextext{\idxcode{\#elif}}% +\terminal{\# elif } constant-expression new-line \opt{group} \end{ncsimplebnf} -causes the implementation to behave -in an \impldef{\tcode{\#pragma}} manner. -The behavior may cause translation to fail or cause the translator or -the resulting program to behave in a non-conforming manner. -Any pragma that is not recognized by the implementation is ignored. - -\rSec1[cpp.null]{Null directive}% -\indextext{preprocessing directive!null} +check whether the controlling constant expression evaluates to nonzero. \pnum -A preprocessing directive of the form -\begin{ncsimplebnf} -\terminal{\#} new-line -\end{ncsimplebnf} -has no effect. - -\rSec1[cpp.predefined]{Predefined macro names} -\indextext{macro!predefined}% -\indextext{name!predefined macro|see{macro, predefined}} +Prior to evaluation, +macro invocations in the list of preprocessing tokens +that will become the controlling constant expression +are replaced +(except for those macro names modified by the +\tcode{defined} +unary operator), +just as in normal text. +If the token +\tcode{defined} +is generated as a result of this replacement process +or use of the +\tcode{defined} +unary operator does not match one of the two specified forms +prior to macro replacement, +the behavior is undefined. \pnum -The following macro names shall be defined by the implementation: - -\begin{description} - -\item -\indextext{\idxxname{cplusplus}}% -\xname{cplusplus}\\ -The integer literal \tcode{\cppver}. +After all replacements due to macro expansion and +evaluations of +\grammarterm{defined-macro-expression}s, +\grammarterm{has-include-expression}s, and +\grammarterm{has-attribute-expression}s +have been performed, +all remaining identifiers and keywords, +except for +\tcode{true} +and +\tcode{false}, +are replaced with the \grammarterm{pp-number} +\tcode{0}, +and then each preprocessing token is converted into a token. \begin{note} -Future revisions of this document will -replace the value of this macro with a greater value. +An alternative +token\iref{lex.operators} is not an identifier, +even when its spelling consists entirely of letters and underscores. +Therefore it is not subject to this replacement. \end{note} -\item The names listed in \tref{cpp.predefined.ft}.\\ -The macros defined in \tref{cpp.predefined.ft} shall be defined to -the corresponding integer literal. +\pnum +The resulting tokens comprise the controlling constant expression +which is evaluated according to the rules of~\ref{expr.const} +using arithmetic that has at least the ranges specified +in~\ref{support.limits}. For the purposes of this token conversion and evaluation +all signed and unsigned integer types +act as if they have the same representation as, respectively, +\tcode{intmax_t} or \tcode{uintmax_t}\iref{cstdint.syn}. \begin{note} -Future revisions of this document might replace -the values of these macros with greater values. +Thus on an +implementation where \tcode{std::numeric_limits::max()} is \tcode{0x7FFF} +and \tcode{std::numeric_limits::max()} is \tcode{0xFFFF}, +the integer literal \tcode{0x8000} is signed and positive within a \tcode{\#if} +expression even though it is unsigned in translation phase +7\iref{lex.phases}. \end{note} - -\item -\indextext{__date__@\mname{DATE}}% -\mname{DATE}\\ -The date of translation of the source file: -a character string literal of the form -\tcode{"Mmm~dd~yyyy"}, -where the names of the months are the same as those generated -by the -\tcode{asctime} -function, -and the first character of -\tcode{dd} -is a space character if the value is less than 10. -If the date of translation is not available, -an \impldef{text of \mname{DATE} when date of translation is not available} valid date -shall be supplied. - -\item -\indextext{__file__@\mname{FILE}}% -\mname{FILE}\\ -The presumed name of the current source file (a character string -literal). -\begin{footnote} -The presumed source file name can be changed by the \tcode{\#line} directive. -\end{footnote} - -\item -\indextext{__line__@\mname{LINE}}% -\mname{LINE}\\ -The presumed line number (within the current source file) of the current source line -(an integer literal). -\begin{footnote} -The presumed line number can be changed by the \tcode{\#line} directive. -\end{footnote} - -\item -\indextext{__stdc_hosted__@\mname{STDC_HOSTED}}% -\indextext{implementation!hosted}% -\indextext{implementation!freestanding}% -\mname{STDC_HOSTED}\\ -The integer literal \tcode{1} -if the implementation is a hosted implementation or -the integer literal \tcode{0} -if it is a freestanding implementation\iref{intro.compliance}. - -\item -\indextext{__stdcpp_default_new_alignment__@\mname{STDCPP_DEFAULT_NEW_ALIGNMENT}}% -\mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\\ -An integer literal of type \tcode{std::size_t} -whose value is the alignment guaranteed -by a call to \tcode{operator new(std::size_t)} -or \tcode{operator new[](std::size_t)}. +This includes interpreting \grammarterm{character-literal}s +according to the rules in \ref{lex.ccon}. \begin{note} -Larger alignments will be passed to -\tcode{operator new(std::size_t, std::align_val_t)}, etc.\iref{expr.new}. +The associated character encodings of literals are the same +in \tcode{\#if} and \tcode{\#elif} directives and in any expression. \end{note} +Each subexpression with type +\tcode{bool} +is subjected to integral promotion before processing continues. -\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}\\ -The time of translation of the source file: -a character string literal of the form -\tcode{"hh:mm:ss"} -as in the time generated by the -\tcode{asctime} -function. -If the time of translation is not available, -an \impldef{text of \mname{TIME} when time of translation is not available} valid time shall be supplied. -\end{description} +\pnum +Preprocessing directives of the forms +\begin{ncsimplebnf}\obeyspaces +\terminal{\# ifdef } identifier new-line \opt{group}\br +\indextext{\idxcode{\#ifdef}}% +\terminal{\# ifndef } identifier new-line \opt{group}\br +\indextext{\idxcode{\#ifndef}}% +\terminal{\# elifdef } identifier new-line \opt{group}\br +\indextext{\idxcode{\#elifdef}}% +\terminal{\# elifndef} identifier new-line \opt{group} +\indextext{\idxcode{\#elifndef}}% +\end{ncsimplebnf} +check whether the identifier is or is not currently defined as a macro name. +Their conditions are equivalent to +\tcode{\#if} \tcode{defined} \grammarterm{identifier}, +\tcode{\#if} \tcode{!defined} \grammarterm{identifier}, +\tcode{\#elif} \tcode{defined} \grammarterm{identifier}, and +\tcode{\#elif} \tcode{!defined} \grammarterm{identifier}, +respectively. -\indextext{macro!feature-test}% -\indextext{feature-test macro|see{macro, feature-test}}% -\begin{LongTable}{Feature-test macros}{cpp.predefined.ft}{ll} -\\ \topline -\lhdr{Macro name} & \rhdr{Value} \\ \capsep -\endfirsthead -\continuedcaption \\ -\hline -\lhdr{Name} & \rhdr{Value} \\ \capsep -\endhead -\defnxname{cpp_aggregate_bases} & \tcode{201603L} \\ \rowsep -\defnxname{cpp_aggregate_nsdmi} & \tcode{201304L} \\ \rowsep -\defnxname{cpp_aggregate_paren_init} & \tcode{201902L} \\ \rowsep -\defnxname{cpp_alias_templates} & \tcode{200704L} \\ \rowsep -\defnxname{cpp_aligned_new} & \tcode{201606L} \\ \rowsep -\defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep -\defnxname{cpp_auto_cast} & \tcode{202110L} \\ \rowsep -\defnxname{cpp_binary_literals} & \tcode{201304L} \\ \rowsep -\defnxname{cpp_capture_star_this} & \tcode{201603L} \\ \rowsep -\defnxname{cpp_char8_t} & \tcode{202207L} \\ \rowsep -\defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep -\defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep -\defnxname{cpp_constexpr} & \tcode{202406L} \\ \rowsep -\defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep -\defnxname{cpp_consteval} & \tcode{202211L} \\ \rowsep -\defnxname{cpp_constinit} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep -\defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep -\defnxname{cpp_deduction_guides} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_delegating_constructors} & \tcode{200604L} \\ \rowsep -\defnxname{cpp_deleted_function} & \tcode{202403L} \\ \rowsep -\defnxname{cpp_designated_initializers} & \tcode{201707L} \\ \rowsep -\defnxname{cpp_enumerator_attributes} & \tcode{201411L} \\ \rowsep -\defnxname{cpp_explicit_this_parameter} & \tcode{202110L} \\ \rowsep -\defnxname{cpp_fold_expressions} & \tcode{201603L} \\ \rowsep -\defnxname{cpp_generic_lambdas} & \tcode{201707L} \\ \rowsep -\defnxname{cpp_guaranteed_copy_elision} & \tcode{201606L} \\ \rowsep -\defnxname{cpp_hex_float} & \tcode{201603L} \\ \rowsep -\defnxname{cpp_if_consteval} & \tcode{202106L} \\ \rowsep -\defnxname{cpp_if_constexpr} & \tcode{201606L} \\ \rowsep -\defnxname{cpp_impl_coroutine} & \tcode{201902L} \\ \rowsep -\defnxname{cpp_impl_destroying_delete} & \tcode{201806L} \\ \rowsep -\defnxname{cpp_impl_three_way_comparison} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_implicit_move} & \tcode{202207L} \\ \rowsep -\defnxname{cpp_inheriting_constructors} & \tcode{201511L} \\ \rowsep -\defnxname{cpp_init_captures} & \tcode{201803L} \\ \rowsep -\defnxname{cpp_initializer_lists} & \tcode{200806L} \\ \rowsep -\defnxname{cpp_inline_variables} & \tcode{201606L} \\ \rowsep -\defnxname{cpp_lambdas} & \tcode{200907L} \\ \rowsep -\defnxname{cpp_modules} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_multidimensional_subscript} & \tcode{202211L} \\ \rowsep -\defnxname{cpp_named_character_escapes} & \tcode{202207L} \\ \rowsep -\defnxname{cpp_namespace_attributes} & \tcode{201411L} \\ \rowsep -\defnxname{cpp_noexcept_function_type} & \tcode{201510L} \\ \rowsep -\defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep -\defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep -\defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep -\defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep -\defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep -\defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep -\defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep -\defnxname{cpp_ref_qualifiers} & \tcode{200710L} \\ \rowsep -\defnxname{cpp_return_type_deduction} & \tcode{201304L} \\ \rowsep -\defnxname{cpp_rvalue_references} & \tcode{200610L} \\ \rowsep -\defnxname{cpp_size_t_suffix} & \tcode{202011L} \\ \rowsep -\defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep -\defnxname{cpp_static_assert} & \tcode{202306L} \\ \rowsep -\defnxname{cpp_static_call_operator} & \tcode{202207L} \\ \rowsep -\defnxname{cpp_structured_bindings} & \tcode{202403L} \\ \rowsep -\defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep -\defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep -\defnxname{cpp_unicode_characters} & \tcode{200704L} \\ \rowsep -\defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep -\defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep -\defnxname{cpp_using_enum} & \tcode{201907L} \\ \rowsep -\defnxname{cpp_variable_templates} & \tcode{201304L} \\ \rowsep -\defnxname{cpp_variadic_friend} & \tcode{202403L} \\ \rowsep -\defnxname{cpp_variadic_templates} & \tcode{200704L} \\ \rowsep -\defnxname{cpp_variadic_using} & \tcode{201611L} \\ -\end{LongTable} +\pnum +Each directive's condition is checked in order. +If it evaluates to false (zero), +the group that it controls is skipped: +directives are processed only through the name that determines +the directive in order to keep track of the level +of nested conditionals; +the rest of the directives' preprocessing tokens are ignored, +as are the other preprocessing tokens in the group. +Only the first group +whose control condition evaluates to true (nonzero) is processed; +any following groups are skipped and their controlling directives +are processed as if they were in a group that is skipped. +If none of the conditions evaluates to true, +and there is a +\tcode{\#else} +\indextext{\idxcode{\#else}}% +directive, +the group controlled by the +\tcode{\#else} +is processed; lacking a +\tcode{\#else} +directive, all the groups until the +\tcode{\#endif} +\indextext{\idxcode{\#endif}}% +are skipped.% +\begin{footnote} +As indicated by the syntax, +a preprocessing token cannot follow a +\tcode{\#else} +or +\tcode{\#endif} +directive before the terminating new-line character. +However, +comments can appear anywhere in a source file, +including within a preprocessing directive. +\end{footnote} \pnum -The following macro names are conditionally defined by the implementation: +\begin{example} +This demonstrates a way to include a library \tcode{optional} facility +only if it is available: -\begin{description} -\item -\indextext{__stdc__@\mname{STDC}}% -\mname{STDC}\\ -Whether \mname{STDC} is predefined and if so, what its value is, -are \impldef{definition and meaning of \mname{STDC}}. +\begin{codeblock} +#if __has_include() +# include +# if __cpp_lib_optional >= 201603 +# define have_optional 1 +# endif +#elif __has_include() +# include +# if __cpp_lib_experimental_optional >= 201411 +# define have_optional 1 +# define experimental_optional 1 +# endif +#endif +#ifndef have_optional +# define have_optional 0 +#endif +\end{codeblock} +\end{example} -\item -\indextext{__stdc_mb_might_neq_wc__@\mname{STDC_MB_MIGHT_NEQ_WC}}% -\mname{STDC_MB_MIGHT_NEQ_WC}\\ -The integer literal \tcode{1}, intended to indicate that, in the encoding for -\keyword{wchar_t}, a member of the basic character set need not have a code value equal to -its value when used as the lone character in an ordinary character literal. +\pnum +\begin{example} +This demonstrates a way to use the attribute \tcode{[[acme::deprecated]]} +only if it is available. +\begin{codeblock} +#if __has_cpp_attribute(acme::deprecated) +# define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]] +#else +# define ATTR_DEPRECATED(msg) [[deprecated(msg)]] +#endif +ATTR_DEPRECATED("This function is deprecated") void anvil(); +\end{codeblock} +\end{example} -\item -\indextext{__stdc_version__@\mname{STDC_VERSION}}% -\mname{STDC_VERSION}\\ -Whether \mname{STDC_VERSION} is predefined and if so, what its value is, -are \impldef{definition and meaning of \mname{STDC_VERSION}}. +\rSec1[cpp.include]{Source file inclusion} +\indextext{preprocessing directive!header inclusion} +\indextext{preprocessing directive!source-file inclusion} +\indextext{inclusion!source file|see{preprocessing directive, source-file inclusion}}% +\indextext{\idxcode{\#include}}% -\item -\indextext{__stdc_iso_10646__@\mname{STDC_ISO_10646}}% -\mname{STDC_ISO_10646}\\ -An integer literal of the form \tcode{yyyymmL} -(for example, \tcode{199712L}). -Whether \mname{STDC_ISO_10646} is predefined and -if so, what its value is, -are \impldef{presence and value of \mname{STDC_ISO_10646}}. +\pnum +A +\tcode{\#include} +directive shall identify a header or source file +that can be processed by the implementation. -\item -\indextext{__stdcpp_threads__@\mname{STDCPP_THREADS}}% -\mname{STDCPP_THREADS}\\ -Defined, and has the value integer literal 1, if and only if a program -can have more than one thread of execution\iref{intro.multithread}. +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# include <} h-char-sequence \terminal{>} new-line +\end{ncsimplebnf} +searches a sequence of +\impldef{sequence of places searched for a header} +places +for a header identified uniquely by the specified sequence +between the +\tcode{<} +and +\tcode{>} +delimiters, +and causes the replacement of that +directive by the entire contents of the header. +How the places are specified +or the header identified +is \impldef{search locations for \tcode{<>} header}. -\end{description} +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# include "} q-char-sequence \terminal{"} new-line +\end{ncsimplebnf} +causes the replacement of that +directive by the entire contents of the +source file identified by the specified sequence between the +\tcode{"} +delimiters. +The named source file is searched for in an +\impldef{manner of search for included source file} +manner. +If this search is not supported, +or if the search fails, +the directive is reprocessed as if it read +\begin{ncsimplebnf} +\terminal{\# include <} h-char-sequence \terminal{>} new-line +\end{ncsimplebnf} +with the identical contained sequence (including +\tcode{>} +characters, if any) from the original directive. \pnum -The values of the predefined macros -(except for -\mname{FILE} -and -\mname{LINE}) -remain constant throughout the translation unit. +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# include} pp-tokens new-line +\end{ncsimplebnf} +(that does not match one of the two previous forms) is permitted. +The preprocessing tokens after +\tcode{include} +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). +If the directive resulting after all replacements does not match +one of the two previous forms, the behavior is +undefined. +\begin{footnote} +Note that adjacent \grammarterm{string-literal}s are not concatenated into +a single \grammarterm{string-literal} +(see the translation phases in~\ref{lex.phases}); +thus, an expansion that results in two \grammarterm{string-literal}s is an +invalid directive. +\end{footnote} +The method by which a sequence of preprocessing tokens between a +\tcode{<} +and a +\tcode{>} +preprocessing token pair or a pair of +\tcode{"} +characters is combined into a single header name +preprocessing token is \impldef{search locations for \tcode{""""} header}. \pnum -If any of the pre-defined macro names in this subclause, -or the identifier -\tcode{defined}, -is the subject of a -\tcode{\#define} -or a -\tcode{\#undef} -preprocessing directive, -the behavior is undefined. -Any other predefined macro names shall begin with a -leading underscore followed by an uppercase letter or a second -underscore. +The implementation shall provide unique mappings for +sequences consisting of one or more +\grammarterm{nondigit}{s} or \grammarterm{digit}{s}\iref{lex.name} +followed by a period +(\tcode{.}) +and a single +\grammarterm{nondigit}. +The first character shall not be a \grammarterm{digit}. +The implementation may ignore distinctions of alphabetical case. -\rSec1[cpp.pragma.op]{Pragma operator}% -\indextext{macro!pragma operator}% -\indextext{operator!pragma|see{macro, pragma operator}} +\pnum +A +\tcode{\#include} +preprocessing directive may appear +in a source file that has been read because of a +\tcode{\#include} +directive in another file, +up to an \impldef{nesting limit for \tcode{\#include} directives} nesting limit. \pnum -A unary operator expression of the form: +If the header identified by the \grammarterm{header-name} +denotes an importable header\iref{module.import}, +it is +\impldef{whether source file inclusion of importable header +is replaced with \tcode{import} directive} +whether the \tcode{\#include} preprocessing directive +is instead replaced by an \tcode{import} directive\iref{cpp.import} of the form \begin{ncbnf} -\terminal{_Pragma} \terminal{(} string-literal \terminal{)} +\terminal{import} header-name \terminal{;} new-line \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 -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 -to produce preprocessing tokens that are executed as if they were the -\grammarterm{pp-tokens} in a pragma directive. The original four preprocessing -tokens in the unary operator expression are removed. \pnum -\begin{example} -\begin{codeblock} -#pragma listing on "..\listing.dir" -\end{codeblock} -can also be expressed as: +\begin{note} +An implementation can provide a mechanism for making arbitrary +source files available to the \tcode{< >} search. +However, using the \tcode{< >} form for headers provided +with the implementation and the \tcode{" "} form for sources +outside the control of the implementation +achieves wider portability. For instance: + \begin{codeblock} -_Pragma ( "listing on \"..\\listing.dir\"" ) +#include +#include +#include "usefullib.h" +#include "myprog.h" \end{codeblock} -The latter form is processed in the same way whether it appears literally -as shown, or results from macro replacement, as in: -\begin{codeblock} -#define LISTING(x) PRAGMA(listing on #x) -#define PRAGMA(x) _Pragma(#x) -LISTING( ..\listing.dir ) +\end{note} + +\pnum +\begin{example} +This illustrates macro-replaced +\tcode{\#include} +directives: + +\begin{codeblock} +#if VERSION == 1 + #define INCFILE "vers1.h" +#elif VERSION == 2 + #define INCFILE "vers2.h" // and so on +#else + #define INCFILE "versN.h" +#endif +#include INCFILE \end{codeblock} \end{example} -\indextext{preprocessing directive|)} diff --git a/source/statements.tex b/source/statements.tex index 9940ee28de..356110e99d 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -1,5 +1,5 @@ %!TEX root = std.tex -\rSec0[stmt.stmt]{Statements}% +\rSec0[stmt]{Statements}% \indextext{statement|(} \gramSec[gram.stmt]{Statements} @@ -19,8 +19,8 @@ \opt{attribute-specifier-seq} selection-statement\br \opt{attribute-specifier-seq} iteration-statement\br \opt{attribute-specifier-seq} jump-statement\br - declaration-statement\br - \opt{attribute-specifier-seq} try-block + \opt{attribute-specifier-seq} try-block\br + declaration-statement \end{bnf} \begin{bnf} @@ -92,7 +92,7 @@ the \grammarterm{condition} is a structured binding declaration\iref{dcl.pre}. A \grammarterm{condition} that is neither an \grammarterm{expression} nor a structured binding declaration -is a declaration\iref{dcl.dcl}. +is a declaration\iref{dcl}. The \grammarterm{declarator} shall not specify a function or an array. The \grammarterm{decl-specifier-seq} shall not define a class or enumeration. If the \keyword{auto} \grammarterm{type-specifier} appears in @@ -1033,6 +1033,751 @@ \indextext{label}% label\iref{stmt.label} located in the current function. +\rSec1[except]{Try block statements}% +\indextext{exception handling|(} + +\indextext{exception object|see{exception handling, exception object}}% +\indextext{object!exception|see{exception handling, exception object}} + +\rSec2[except.pre]{General} + +\pnum +Exception handling provides a way of transferring control and information +from a point in the execution of a thread to an exception handler +associated with a point previously passed by the execution. +A handler will be invoked only by throwing an exception +in code executed in the handler's try block +or in functions called from the handler's try block. + +\indextext{\idxcode{try}}% +% +\begin{bnf} +\nontermdef{try-block}\br + \keyword{try} compound-statement handler-seq +\end{bnf} + +\indextext{\idxcode{try}}% +% +\begin{bnf} +\nontermdef{function-try-block}\br + \keyword{try} \opt{ctor-initializer} compound-statement handler-seq +\end{bnf} + +\begin{bnf} +\nontermdef{handler-seq}\br + handler \opt{handler-seq} +\end{bnf} + +\indextext{\idxcode{catch}}% +% +\begin{bnf} +\nontermdef{handler}\br + \keyword{catch} \terminal{(} exception-declaration \terminal{)} compound-statement +\end{bnf} + +\begin{bnf} +\nontermdef{exception-declaration}\br + \opt{attribute-specifier-seq} type-specifier-seq declarator\br + \opt{attribute-specifier-seq} type-specifier-seq \opt{abstract-declarator}\br + \terminal{...} +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} in an \grammarterm{exception-declaration} +appertains to the parameter of the catch clause\iref{except.handle}. + +\pnum +In this Clause, ``before'' and ``after'' refer to the +``sequenced before'' relation\iref{intro.execution}. + +\pnum +\indextext{exception handling!try block}% +\indextext{try block|see{exception handling, try block}}% +Within this Clause +``try block'' is taken to mean both \grammarterm{try-block} and +\grammarterm{function-try-block}. + +\pnum +\indextext{exception handling!\idxcode{switch}}% +\indextext{exception handling!handler}% +\indextext{handler|see{exception handling, handler}}%\indextext{exception handling!\idxcode{goto}}% +\indextext{\idxcode{goto}!and try block}% +\indextext{\idxcode{switch}!and try block}% +\indextext{\idxcode{goto}!and handler}% +\indextext{\idxcode{switch}!and handler}% +The \grammarterm{compound-statement} of a try block or of a handler is a +control-flow-limited statement\iref{stmt.label}. +\begin{example} +\begin{codeblock} +void f() { + goto l1; // error + goto l2; // error + try { + goto l1; // OK + goto l2; // error + l1: ; + } catch (...) { + l2: ; + goto l1; // error + goto l2; // OK + } +} + +\end{codeblock} +\end{example} + +\pnum +\indextext{\idxcode{goto}!and try block}% +\indextext{\idxcode{switch}!and try block}% +\indextext{\idxcode{return}!and try block}% +\indextext{\idxcode{continue}!and try block}% +\indextext{\idxcode{goto}!and handler}% +\indextext{\idxcode{switch}!and handler}% +\indextext{\idxcode{return}!and handler}% +\indextext{\idxcode{continue}!and handler}% +A +\keyword{goto}, +\keyword{break}, +\keyword{return}, +or +\keyword{continue} +statement can be used to transfer control out of +a try block or handler. +When this happens, each variable declared in the try block +will be destroyed in the context that +directly contains its declaration. +\begin{example} +\begin{codeblock} +lab: try { + T1 t1; + try { + T2 t2; + if (@\grammarterm{condition}@) + goto lab; + } catch(...) { @\tcode{/* handler 2 */}@ } + } catch(...) { @\tcode{/* handler 1 */}@ } +\end{codeblock} + +Here, executing +\tcode{goto lab;} +will destroy first +\tcode{t2}, +then +\tcode{t1}, +assuming the +\grammarterm{condition} +does not declare a variable. +Any exception thrown while destroying +\tcode{t2} +will result in executing +\tcode{handler 2}; +any exception thrown while destroying +\tcode{t1} +will result in executing +\tcode{handler 1}. +\end{example} + +\pnum +\indextext{function try block|see{exception handling, function try block}}% +\indextext{exception handling!function try block}% +A +\grammarterm{function-try-block} +associates a +\grammarterm{handler-seq} +with the +\grammarterm{ctor-initializer}, +if present, and the +\grammarterm{compound-statement}. +An exception +thrown during the execution of the +\grammarterm{compound-statement} +or, for constructors and destructors, during the initialization or +destruction, respectively, of the class's subobjects, +transfers control to a handler in a +\grammarterm{function-try-block} +in the same way as an exception thrown during the execution of a +\grammarterm{try-block} +transfers control to other handlers. +\begin{example} +\begin{codeblock} +int f(int); +class C { + int i; + double d; +public: + C(int, double); +}; + +C::C(int ii, double id) +try : i(f(ii)), d(id) { + // constructor statements +} catch (...) { + // handles exceptions thrown from the ctor-initializer and from the constructor statements +} +\end{codeblock} +\end{example} + +\rSec2[except.throw]{Throwing an exception}% +\indextext{exception handling!throwing}% +\indextext{throwing|see{exception handling, throwing}} + +\pnum +Throwing an exception transfers control to a handler. +\begin{note} +An exception can be thrown from one of the following contexts: +\grammarterm{throw-expression}{s}\iref{expr.throw}, +allocation functions\iref{basic.stc.dynamic.allocation}, +\keyword{dynamic_cast}\iref{expr.dynamic.cast}, +\keyword{typeid}\iref{expr.typeid}, +\grammarterm{new-expression}{s}\iref{expr.new}, and standard library +functions\iref{structure.specifications}. +\end{note} +An object is passed and the type of that object determines which handlers +can catch it. +\begin{example} +\begin{codeblock} +throw "Help!"; +\end{codeblock} +can be caught by a +\grammarterm{handler} +of +\keyword{const} +\tcode{\keyword{char}*} +type: +\begin{codeblock} +try { + // ... +} catch(const char* p) { + // handle character string exceptions here +} +\end{codeblock} +and +\begin{codeblock} +class Overflow { +public: + Overflow(char,double,double); +}; + +void f(double x) { + throw Overflow('+',x,3.45e107); +} +\end{codeblock} +can be caught by a handler for exceptions of type +\tcode{Overflow}: +\begin{codeblock} +try { + f(1.2); +} catch(Overflow& oo) { + // handle exceptions of type \tcode{Overflow} here +} +\end{codeblock} +\end{example} + +\pnum +\indextext{exception handling!throwing}% +\indextext{exception handling!handler}% +\indextext{exception handling!nearest handler}% +When an exception is thrown, control is transferred to the nearest handler with +a matching type\iref{except.handle}; ``nearest'' means the handler +for which the +\grammarterm{compound-statement} or +\grammarterm{ctor-initializer} +following the +\keyword{try} +keyword was most recently entered by the thread of control and not yet exited. + +\pnum +Throwing an exception +initializes an object with dynamic storage duration, +called the +\defnx{exception object}{exception handling!exception object}. +If the type of the exception object would be +an incomplete type\iref{basic.types.general}, +an abstract class type\iref{class.abstract}, +or a pointer to an incomplete type other than +\cv{}~\keyword{void}\iref{basic.compound}, +the program is ill-formed. + +\pnum +\indextext{exception handling!memory}% +\indextext{exception handling!rethrowing}% +\indextext{exception handling!exception object}% +The memory for the exception object is +allocated in an unspecified way, except as noted in~\ref{basic.stc.dynamic.allocation}. +If a handler exits by rethrowing, control is passed to another handler for +the same exception object. +The points of potential destruction for the exception object are: +\begin{itemize} +\item +when an active handler for the exception exits by +any means other than +rethrowing, +immediately after the destruction of the object (if any) +declared in the \grammarterm{exception-declaration} in the handler; + +\item +when an object of type \tcode{std::exception_ptr}\iref{propagation} +that refers to the exception object is destroyed, +before the destructor of \tcode{std::exception_ptr} returns. +\end{itemize} + +Among all points of potential destruction for the exception object, +there is an unspecified last one +where the exception object is destroyed. +All other points happen before that last one\iref{intro.races}. +\begin{note} +No other thread synchronization is implied in exception handling. +\end{note} +The implementation may then +deallocate the memory for the exception object; any such deallocation +is done in an unspecified way. +\begin{note} +A thrown exception does not +propagate to other threads unless caught, stored, and rethrown using +appropriate library functions; see~\ref{propagation} and~\ref{futures}. +\end{note} + +\pnum +\indextext{exception handling!exception object!constructor}% +\indextext{exception handling!exception object!destructor}% +Let \tcode{T} denote the type of the exception object. +Copy-initialization of an object of type \tcode{T} from +an lvalue of type \tcode{const T} in a context unrelated to \tcode{T} +shall be well-formed. +If \tcode{T} is a class type, +the selected constructor is odr-used\iref{basic.def.odr} and +the destructor of \tcode{T} is potentially invoked\iref{class.dtor}. + +\pnum +An exception is considered uncaught +after completing the initialization of the exception object +until completing the activation of a handler for the exception\iref{except.handle}. +\begin{note} +As a consequence, an exception is considered uncaught +during any stack unwinding resulting from it being thrown. +\end{note} + +\pnum +\indextext{exception handling!rethrow}% +\indextext{rethrow|see{exception handling, rethrow}}% +An exception is considered caught when a handler for that exception +becomes active\iref{except.handle}. +\begin{note} +An exception can have active handlers and still be considered uncaught if +it is rethrown. +\end{note} + +\pnum +If an exception is rethrown\iref{expr.throw,propagation}, +it is considered uncaught from the point of rethrow +until the rethrown exception is caught. +\indexlibraryglobal{uncaught_exceptions}% +\begin{note} +The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} +returns the number of uncaught exceptions in the current thread. +\end{note} + +\pnum +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If the exception handling mechanism +handling an uncaught exception +directly invokes a function that exits via an +exception, the function \tcode{std::terminate} is invoked\iref{except.terminate}. +\begin{example} +\begin{codeblock} +struct C { + C() { } + C(const C&) { + if (std::uncaught_exceptions()) { + throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object\iref{except.handle} + } + } +}; + +int main() { + try { + throw C(); // calls \tcode{std::terminate} if construction of the handler's + // \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision} + } catch(C) { } +} +\end{codeblock} +\end{example} +\begin{note} +If a destructor directly invoked by stack unwinding exits via an exception, +\tcode{std::terminate} is invoked. +\end{note} + + +\rSec2[except.ctor]{Stack unwinding}% +\indextext{exception handling!constructors and destructors}% +\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}% +\indextext{destructor!exception handling|see{exception handling, constructors and destructors}} + +\pnum +\indextext{unwinding!stack}% +As control passes from the point where an exception is thrown +to a handler, +objects are destroyed by a process, +specified in this subclause, called \defn{stack unwinding}. + +\pnum +Each object with automatic storage duration is destroyed if it has been +constructed, but not yet destroyed, +since the try block was entered. +If an exception is thrown during the destruction of temporaries or +local variables for a \keyword{return} statement\iref{stmt.return}, +the destructor for the returned object (if any) is also invoked. +The objects are destroyed in the reverse order of the completion +of their construction. +\begin{example} +\begin{codeblock} +struct A { }; + +struct Y { ~Y() noexcept(false) { throw 0; } }; + +A f() { + try { + A a; + Y y; + A b; + return {}; // \#1 + } catch (...) { + } + return {}; // \#2 +} +\end{codeblock} +At \#1, the returned object of type \tcode{A} is constructed. +Then, the local variable \tcode{b} is destroyed\iref{stmt.jump}. +Next, the local variable \tcode{y} is destroyed, +causing stack unwinding, +resulting in the destruction of the returned object, +followed by the destruction of the local variable \tcode{a}. +Finally, the returned object is constructed again at \#2. +\end{example} + +\pnum +If the initialization of an object +other than by delegating constructor +is terminated by an exception, +the destructor is invoked for +each of the object's subobjects +that were known to be initialized by the object's initialization and +whose initialization has completed\iref{dcl.init}. +\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} +\indextext{subobject!initialized, known to be}% +A subobject is \defn{known to be initialized} +if it is not an anonymous union member and +its initialization is specified +\begin{itemize} +\item in \ref{expr.prim.lambda.capture} for the initialization of +the closure object when evaluating a \grammarterm{lambda-expression}, +\item in \ref{dcl.init.general} for +default-initialization, value-initialization, or direct-initialization +of an array, +\item in \ref{dcl.init.aggr} for aggregate initialization, +\item in \ref{class.copy.ctor} for initialization by defaulted copy/move constructor, +\item in \ref{class.base.init} for initialization by constructor, +\item in \ref{class.inhctor.init} for initialization by inherited constructor. +\end{itemize} +\begin{note} +This includes virtual base class subobjects +if the initialization +is for a complete object, and +can include variant members +that were nominated explicitly by +a \grammarterm{mem-initializer} or \grammarterm{designated-initializer-clause} or +that have a default member initializer. +\end{note} +If the destructor of an object is terminated by an exception, +each destructor invocation +that would be performed after executing the body of the destructor\iref{class.dtor} and +that has not yet begun execution +is performed. +\begin{note} +This includes virtual base class subobjects if +the destructor was invoked for a complete object. +\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, +if any. + +\pnum +If the \grammarterm{compound-statement} +of the \grammarterm{function-body} +of a delegating constructor +for an object exits via +an exception, the object's destructor is invoked. +Such destruction is sequenced before entering a handler of the +\grammarterm{function-try-block} of a delegating constructor for that object, if any. + +\pnum +\begin{note} +If the object was allocated by a \grammarterm{new-expression}\iref{expr.new}, +the matching deallocation function\iref{basic.stc.dynamic.deallocation}, +if any, is called to free the storage occupied by the object. +\end{note} + + +\rSec2[except.handle]{Handling an exception} +\indextext{exception handling!handler|(}% + +\pnum +The +\grammarterm{exception-declaration} +in a +\grammarterm{handler} +describes the type(s) of exceptions that can cause +that +\grammarterm{handler} +to be entered. +\indextext{exception handling!handler!incomplete type in}% +\indextext{exception handling!handler!rvalue reference in}% +\indextext{exception handling!handler!array in}% +\indextext{exception handling!handler!pointer to function in}% +The +\grammarterm{exception-declaration} +shall not denote an incomplete type, an abstract class type, or an rvalue reference type. +The +\grammarterm{exception-declaration} +shall not denote a pointer or reference to an +incomplete type, other than ``pointer to \cv{}~\keyword{void}''. + +\pnum +A handler of type +\indextext{array!handler of type}% +``array of \tcode{T}'' or +\indextext{function!handler of type}% +function type \tcode{T} +is adjusted to be of type +``pointer to \tcode{T}''. + +\pnum +\indextext{exception handling!handler!match|(}% +A +\grammarterm{handler} +is a match for +an exception object +of type +\tcode{E} +if +\begin{itemize} +\item% +The \grammarterm{handler} is of type \cv{}~\tcode{T} or +\cv{}~\tcode{T\&} and +\tcode{E} and \tcode{T} +are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or +\item% +the \grammarterm{handler} is of type \cv{}~\tcode{T} or +\cv{}~\tcode{T\&} and +\tcode{T} is an unambiguous public base class of \tcode{E}, or +\item% +the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} +where \tcode{T} is a pointer or pointer-to-member type and +\tcode{E} is a pointer or pointer-to-member type +that can be converted to \tcode{T} by one or more of +\begin{itemize} + +\item% +a standard pointer conversion\iref{conv.ptr} not involving conversions +to pointers to private or protected or ambiguous classes +\item% +a function pointer conversion\iref{conv.fctptr} +\item% +a qualification conversion\iref{conv.qual}, or + +\end{itemize} + +\item +the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}. + +\end{itemize} + +\begin{note} +A +\grammarterm{throw-expression} +whose operand is an integer literal with value zero does not match a handler of +pointer or pointer-to-member type. +A handler of reference to array or function type +is never a match for any exception object\iref{expr.throw}. +\end{note} + +\begin{example} +\begin{codeblock} +class Matherr { @\commentellip@ virtual void vf(); }; +class Overflow: public Matherr { @\commentellip@ }; +class Underflow: public Matherr { @\commentellip@ }; +class Zerodivide: public Matherr { @\commentellip@ }; + +void f() { + try { + g(); + } catch (Overflow oo) { + // ... + } catch (Matherr mm) { + // ... + } +} +\end{codeblock} +Here, the +\tcode{Overflow} +handler will catch exceptions of type +\tcode{Overflow} +and the +\tcode{Matherr} +handler will catch exceptions of type +\tcode{Matherr} +and of all types publicly derived from +\tcode{Matherr} +including exceptions of type +\tcode{Underflow} +and +\tcode{Zerodivide}. +\end{example} + +\pnum +The handlers for a try block are tried in order of appearance. +\begin{note} +This makes it possible to write handlers that can never be +executed, for example by placing a handler for a final derived class after +a handler for a corresponding unambiguous public base class. +\end{note} + +\pnum +A +\tcode{...} +in a handler's +\grammarterm{exception-declaration} +specifies a match for any exception. +If present, a +\tcode{...} +handler shall be the last handler for its try block. + +\pnum +If no match is found among the handlers for a try block, +the search for a matching +handler continues in a dynamically surrounding try block +of the same thread. + +\pnum +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If the search for a handler +encounters the outermost block of a function with a +non-throwing exception specification, +the function \tcode{std::terminate} is invoked\iref{except.terminate}. +\begin{note} +An implementation is not permitted to reject an expression merely because, when +executed, it throws or might +throw an exception from a function with a non-throwing exception specification. +\end{note} +\begin{example} +\begin{codeblock} +extern void f(); // potentially-throwing + +void g() noexcept { + f(); // valid, even if \tcode{f} throws + throw 42; // valid, effectively a call to \tcode{std::terminate} +} +\end{codeblock} +The call to +\tcode{f} +is well-formed despite the possibility for it to throw an exception. +\end{example} + +\pnum +If no matching handler is found, +the function \tcode{std::terminate} is invoked; +whether or not the stack is unwound before this invocation of +\tcode{std::terminate} +is \impldef{stack unwinding before invocation of +\tcode{std::terminate}}\iref{except.terminate}. + +\pnum +A handler is considered \defnx{active}{exception handling!handler!active} when +initialization is complete for the parameter (if any) of the catch clause. +\begin{note} +The stack will have been unwound at that point. +\end{note} +Also, an implicit handler is considered active when +the function \tcode{std::terminate} +is entered due to a throw. A handler is no longer considered active when the +catch clause exits. + +\pnum +\indextext{currently handled exception|see{exception handling, currently handled exception}}% +The exception with the most recently activated handler that is +still active is called the +\defnx{currently handled exception}{exception handling!currently handled exception}. + +\pnum +Referring to any non-static member or base class of an object +in the handler for a +\grammarterm{function-try-block} +of a constructor or destructor for that object results in undefined behavior. + +\pnum +Exceptions thrown in destructors of objects with static storage duration or in +constructors of objects associated with non-block variables with static storage duration are not caught by a +\grammarterm{function-try-block} +on +the \tcode{main} function\iref{basic.start.main}. +Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a +\grammarterm{function-try-block} +on the initial function of the thread. + +\pnum +If a \keyword{return} statement\iref{stmt.return} appears in a handler of the +\grammarterm{function-try-block} +of a +constructor, the program is ill-formed. + +\pnum +The currently handled exception +is rethrown if control reaches the end of a handler of the +\grammarterm{function-try-block} +of a constructor or destructor. +Otherwise, flowing off the end of +the \grammarterm{compound-statement} +of a \grammarterm{handler} +of a \grammarterm{function-try-block} +is equivalent to flowing off the end of +the \grammarterm{compound-statement} +of that function (see \ref{stmt.return}). + +\pnum +The variable declared by the \grammarterm{exception-declaration}, of type +\cv{}~\tcode{T} or \cv{}~\tcode{T\&}, is initialized from the exception object, +of type \tcode{E}, as follows: +\begin{itemize} +\item +if \tcode{T} is a base class of \tcode{E}, +the variable is copy-initialized\iref{dcl.init} +from an lvalue of type \tcode{T} designating the corresponding base class subobject +of the exception object; +\item otherwise, the variable is copy-initialized\iref{dcl.init} +from an lvalue of type \tcode{E} designating the exception object. +\end{itemize} + +The lifetime of the variable ends +when the handler exits, after the +destruction of any objects with automatic storage duration initialized +within the handler. + +\pnum +When the handler declares an object, +any changes to that object will not affect the exception object. +When the handler declares a reference to an object, +any changes to the referenced object are changes to the +exception object and will have effect should that object be rethrown.% +\indextext{exception handling!handler!match|)}% +\indextext{exception handling!handler|)} + \rSec1[stmt.dcl]{Declaration statement}% \indextext{statement!declaration} diff --git a/source/std.tex b/source/std.tex index 2761dbee82..d4e89096d1 100644 --- a/source/std.tex +++ b/source/std.tex @@ -112,16 +112,15 @@ \include{intro} \include{lex} +\include{preprocessor} \include{basic} \include{expressions} \include{statements} \include{declarations} +\include{overloading} \include{modules} \include{classes} -\include{overloading} \include{templates} -\include{exceptions} -\include{preprocessor} \include{lib-intro} \include{support} \include{concepts} diff --git a/source/support.tex b/source/support.tex index bebd8957aa..fda729a263 100644 --- a/source/support.tex +++ b/source/support.tex @@ -3849,7 +3849,7 @@ \begin{itemdescr} \pnum \returns -The number of uncaught exceptions\iref{except.uncaught}. +The number of uncaught exceptions\iref{except.throw} in the current thread. \pnum \remarks diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index fd1251057e..03c9788f16 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -90,6 +90,24 @@ \movedxref{stoptoken.cons}{stopsource} \movedxref{stoptoken.nonmembers}{stopsource} +% https://github.com/cplusplus/draft/pull/7179 +\movedxref{dcl.dcl}{dcl} +\movedxref{diff.cpp03.dcl.dcl}{diff.cpp03.dcl} +\movedxref{diff.cpp11.dcl.dcl}{diff.cpp11.dcl} +\movedxref{diff.cpp14.dcl.dcl}{diff.cpp14.dcl} +\movedxref{diff.cpp17.dcl.dcl}{diff.cpp17.dcl} +\movedxref{diff.stat}{diff.stmt} +\movedxref{stmt.stmt}{stmt} + +% Lexing reorganization +\movedxref{basic.stc.inherit}{basic.stc.general} +\movedxref{except.uncaught}{except.throw} +\movedxref{gram.basic}{gram.module} +\movedxref{gram.except}{gram.stmt} +\movedxref{lex.digraph}{lex.operators} +\removedxref{except.special} +\removedxref{except.special.general} + %%% Deprecated features. %%% Example: %