%!TEX root = std.tex
\rSec0[dcl]{Declarations}%
\indextext{declaration|(}

\gramSec[gram.dcl]{Declarations}

\indextext{linkage specification|see{specification, linkage}}

\rSec1[dcl.pre]{Preamble}

\pnum
Declarations generally specify how names are to be interpreted. Declarations have
the form
\begin{bnf}
\nontermdef{declaration-seq}\br
    declaration \opt{declaration-seq}
\end{bnf}

\begin{bnf}
\nontermdef{declaration}\br
    name-declaration\br
    special-declaration
\end{bnf}

\begin{bnf}
\nontermdef{name-declaration}\br
    block-declaration\br
    nodeclspec-function-declaration\br
    function-definition\br
    friend-type-declaration\br
    template-declaration\br
    deduction-guide\br
    linkage-specification\br
    namespace-definition\br
    empty-declaration\br
    attribute-declaration\br
    module-import-declaration
\end{bnf}

\begin{bnf}
\nontermdef{special-declaration}\br
    explicit-instantiation\br
    explicit-specialization\br
    export-declaration
\end{bnf}

\begin{bnf}
\nontermdef{block-declaration}\br
    simple-declaration\br
    asm-declaration\br
    namespace-alias-definition\br
    using-declaration\br
    using-enum-declaration\br
    using-directive\br
    static_assert-declaration\br
    consteval-block-declaration\br
    alias-declaration\br
    opaque-enum-declaration
\end{bnf}

\begin{bnf}
\nontermdef{nodeclspec-function-declaration}\br
    \opt{attribute-specifier-seq} declarator \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{alias-declaration}\br
    \keyword{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{sb-identifier}\br
    \opt{\terminal{...}} identifier \opt{attribute-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{sb-identifier-list}\br
    sb-identifier\br
    sb-identifier-list \terminal{,} sb-identifier
\end{bnf}

\begin{bnf}
\nontermdef{structured-binding-declaration}\br
    \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} sb-identifier-list \terminal{]}
\end{bnf}

\begin{bnf}
\nontermdef{simple-declaration}\br
    decl-specifier-seq \opt{init-declarator-list} \terminal{;}\br
    attribute-specifier-seq decl-specifier-seq init-declarator-list \terminal{;}\br
    structured-binding-declaration initializer \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{static_assert-message}\br
  unevaluated-string\br
  constant-expression
\end{bnf}

\begin{bnf}
\nontermdef{static_assert-declaration}\br
  \keyword{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br
  \keyword{static_assert} \terminal{(} constant-expression \terminal{,} static_assert-message \terminal{)} \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{consteval-block-declaration}\br
  \keyword{consteval} compound-statement
\end{bnf}

\begin{bnf}
\nontermdef{empty-declaration}\br
    \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{attribute-declaration}\br
    attribute-specifier-seq \terminal{;}
\end{bnf}

\begin{note}
\grammarterm{asm-declaration}{s} are described in~\ref{dcl.asm}, and
\grammarterm{linkage-specification}{s} are described in~\ref{dcl.link};
\grammarterm{function-definition}{s} are described in~\ref{dcl.fct.def} and
\grammarterm{template-declaration}{s} and
\grammarterm{deduction-guide}{s} are described in \ref{temp.deduct.guide};
\grammarterm{namespace-definition}{s} are described in~\ref{namespace.def},
\grammarterm{using-declaration}{s} are described in~\ref{namespace.udecl} and
\grammarterm{using-directive}{s} are described in~\ref{namespace.udir}.
\end{note}

\pnum
\indextext{declaration}%
\indextext{scope}%
Certain declarations contain one or more scopes\iref{basic.scope.scope}.
Unless otherwise stated, utterances in
\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.

\pnum
If a \grammarterm{name-declaration} matches
the syntactic requirements of \grammarterm{friend-type-declaration},
it is a \grammarterm{friend-type-declaration}.

\pnum
A
\grammarterm{simple-declaration} or
\grammarterm{nodeclspec-function-declaration} of the form
\begin{ncsimplebnf}
\opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{init-declarator-list} \terminal{;}
\end{ncsimplebnf}
is divided into three parts.
Attributes are described in~\ref{dcl.attr}.
\grammarterm{decl-specifier}{s}, the principal components of
a \grammarterm{decl-specifier-seq}, are described in~\ref{dcl.spec}.
\grammarterm{declarator}{s}, the components of an
\grammarterm{init-declarator-list}, are described in \ref{dcl.decl}.
The \grammarterm{attribute-specifier-seq}
appertains to each of the entities declared by
the \grammarterm{declarator}{s}
of the \grammarterm{init-declarator-list}.
\begin{note}
In the declaration for an entity, attributes appertaining to that
entity can appear at the start of the declaration and after the
\grammarterm{declarator-id} for that declaration.
\end{note}
\begin{example}
\begin{codeblock}
[[noreturn]] void f [[noreturn]] ();    // OK
\end{codeblock}
\end{example}

\pnum
If a \grammarterm{declarator-id} is a name, the
\grammarterm{init-declarator} and (hence) the declaration introduce that name.
\begin{note}
Otherwise, the \grammarterm{declarator-id} is
a \grammarterm{qualified-id} or
names a destructor or
its \grammarterm{unqualified-id} is a \grammarterm{template-id} and
no name is introduced.
\end{note}
The \grammarterm{defining-type-specifier}{s}\iref{dcl.type} in
the \grammarterm{decl-specifier-seq} and
the recursive \grammarterm{declarator} structure
describe a type\iref{dcl.meaning},
which is then associated with the \grammarterm{declarator-id}.

\pnum
\indextext{identifier}%
\indextext{declarator}%
In a \grammarterm{simple-declaration}, the optional
\grammarterm{init-declarator-list} can be omitted only when declaring a
class\iref{class.pre} or enumeration\iref{dcl.enum}, that is,
when the \grammarterm{decl-specifier-seq} contains either a
\grammarterm{class-specifier}, an \grammarterm{elaborated-type-specifier} with
a \grammarterm{class-key}\iref{class.name}, or an
\grammarterm{enum-specifier}. In these cases and whenever a
\grammarterm{class-specifier} or \grammarterm{enum-specifier} is present in
the \grammarterm{decl-specifier-seq}, the identifiers in these specifiers
are also declared (as
\grammarterm{class-name}{s}, \grammarterm{enum-name}{s}, or
\grammarterm{enumerator}{s}, depending on the syntax). In such cases,
the \grammarterm{decl-specifier-seq} shall (re)introduce one or more names into
the program.
\begin{example}
\begin{codeblock}
enum { };           // error
typedef class { };  // error
\end{codeblock}
\end{example}

\pnum
A \grammarterm{simple-declaration} or a \grammarterm{condition}
with a \grammarterm{structured-binding-declaration} is called
a \defn{structured binding declaration}\iref{dcl.struct.bind}.
Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq}
shall be
\tcode{constexpr},
\tcode{constinit},
\tcode{static},
\tcode{thread_local},
\tcode{auto}\iref{dcl.spec.auto}, or
a \grammarterm{cv-qualifier}.
The declaration shall contain at most one \grammarterm{sb-identifier}
whose \grammarterm{identifier} is preceded by an ellipsis.
If the declaration contains any such \grammarterm{sb-identifier},
it shall declare a templated entity\iref{temp.pre}.
\begin{example}
\begin{codeblock}
template<class T> concept C = true;
C auto [x, y] = std::pair{1, 2};    // error: constrained \grammarterm{placeholder-type-specifier}
                                    // not permitted for structured bindings
\end{codeblock}
\end{example}
The \grammarterm{initializer} shall be
of the form ``\tcode{=} \grammarterm{assignment-expression}'',
of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'',
or
of the form ``\tcode{(} \grammarterm{assignment-expression} \tcode{)}''.
If the \grammarterm{structured-binding-declaration} appears as
a \grammarterm{condition},
the \grammarterm{assignment-expression} shall be of non-union class type.
Otherwise,
the \grammarterm{assignment-expression} shall be of
array or non-union class type.

\pnum
If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef}
specifier, the declaration is a \defnx{typedef declaration}{declaration!\idxcode{typedef}}
and each \grammarterm{declarator-id}
is declared to be a \grammarterm{typedef-name}\iref{dcl.typedef}.
\begin{note}
Such a \grammarterm{declarator-id} is
an \grammarterm{identifier}\iref{class.conv.fct}.
\end{note}
Otherwise, if the type associated with a \grammarterm{declarator-id}
is a function type\iref{dcl.fct},
the declaration is a \defnx{function declaration}{declaration!function}.
Otherwise, if the type associated with a \grammarterm{declarator-id}
is an object or reference type, the declaration is
an \defnx{object declaration}{declaration!object}.
Otherwise, the program is ill-formed.
\begin{example}
\begin{codeblock}
int f(), x;             // OK, function declaration for \tcode{f} and object declaration for \tcode{x}
extern void g(),        // OK, function declaration for \tcode{g}
  y;                    // error: \tcode{void} is not an object type
\end{codeblock}
\end{example}

\pnum
\indextext{initialization!definition and}%
An object definition causes
storage of appropriate size and alignment to be reserved and
any appropriate initialization\iref{dcl.init} to be done.

\pnum
\indextext{definition!declaration as}%
Syntactic components beyond those found in the general form of
\grammarterm{simple-declaration} are added to a function declaration to make a
\grammarterm{function-definition}.
A token sequence starting with \tcode{\{} or \tcode{=}
is treated as a \grammarterm{function-body}\iref{dcl.fct.def.general}
if the type of the \grammarterm{declarator-id}\iref{dcl.meaning.general}
is a function type, and
is otherwise
treated as a \grammarterm{brace-or-equal-initializer}\iref{dcl.init.general}.
\begin{note}
If the declaration acquires a function type through template instantiation,
the program is ill-formed; see \ref{temp.spec.general}.
The function type of a function definition
cannot be specified with a \grammarterm{typedef-name}\iref{dcl.fct}.
\end{note}

\pnum
A \grammarterm{nodeclspec-function-declaration} shall declare a
constructor, destructor, or conversion function.
\begin{note}
Because a member function cannot be subject to a non-defining declaration
outside of a class definition\iref{class.mfct}, a \grammarterm{nodeclspec-function-declaration}
can only be used in a \grammarterm{template-declaration}\iref{temp.pre},
\grammarterm{explicit-instantiation}\iref{temp.explicit}, or
\grammarterm{explicit-specialization}\iref{temp.expl.spec}.
\end{note}

\pnum
If a \grammarterm{static_assert-message}
matches the syntactic requirements of \grammarterm{unevaluated-string},
it is an \grammarterm{unevaluated-string} and
the text of the \grammarterm{static_assert-message} is
the text of the \grammarterm{unevaluated-string}.
Otherwise, a \grammarterm{static_assert-message} shall be an expression $M$
such that
\begin{itemize}
\item
the expression \tcode{$M$.size()} is
implicitly convertible to the type \tcode{std::size_t}, and
\item
the expression \tcode{$M$.data()} is
implicitly convertible to the type ``pointer to \tcode{\keyword{const} \keyword{char}}''.
\end{itemize}

\pnum
\indextext{\idxcode{static_assert}}%
In a \grammarterm{static_assert-declaration},
the \grammarterm{constant-expression} $E$
is contextually converted to \keyword{bool} and
the converted expression shall be a constant expression\iref{expr.const.const}.
If the value of the expression $E$ when so converted is \tcode{true} or
the expression is evaluated in the context of a template definition,
the declaration has no effect and
the \grammarterm{static_assert-message} is
an unevaluated operand\iref{term.unevaluated.operand}.
Otherwise,
the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed} and
\begin{itemize}
\item
the program is ill-formed, and
\item
if the \grammarterm{static_assert-message} is
a \grammarterm{constant-expression} $M$,
\begin{itemize}
\item
\tcode{$M$.size()} shall be a converted constant expression of
type \tcode{std::size_t} and
let $N$ denote the value of that expression,
\item
\tcode{$M$.data()}, implicitly converted to
the type ``pointer to \tcode{\keyword{const} \keyword{char}}'',
shall be a core constant expression and let $D$ denote the converted expression,
\item
for each $i$ where $0 \le i < N$,
\tcode{$D$[$i$]} shall be an integral constant expression, and
\item
the text of the \grammarterm{static_assert-message} is formed by
the sequence of $N$ code units, starting at $D$, of
the ordinary literal encoding\iref{lex.charset}.
\end{itemize}
\end{itemize}

\pnum
\recommended
When a \grammarterm{static_assert-declaration} fails,
the resulting diagnostic message should include the text of
the \grammarterm{static_assert-message}, if one is supplied.
\begin{example}
\begin{codeblock}
static_assert(sizeof(int) == sizeof(void*), "wrong pointer size");
static_assert(sizeof(int[2]));          // OK, narrowing allowed

template <class T>
void f(T t) {
  if constexpr (sizeof(T) == sizeof(int)) {
    use(t);
  } else {
    static_assert(false, "must be int-sized");
  }
}

void g(char c) {
  f(0);             // OK
  f(c);             // error on implementations where \tcode{sizeof(int) > 1}: must be \tcode{int}-sized
}
\end{codeblock}
\end{example}

\pnum
For a \grammarterm{consteval-block-declaration} $D$,
the expression $E$ corresponding to $D$ is:
\begin{codeblock}
  [] static consteval -> void @\grammarterm{compound-statement}@ ()
\end{codeblock}
$E$ shall be a constant expression\iref{expr.const.const}.
\begin{note}
The evaluation of the expression
corresponding to a \grammarterm{consteval-block-declaration}\iref{lex.phases}
can produce injected declarations\iref{expr.const.reflect} as side effects.
\end{note}
\begin{example}
\begin{codeblock}
struct S;
consteval {
  std::meta::define_aggregate(^^S, {});     // OK

  template<class T>
  struct X { };                             // error: local templates are not allowed

  template<class T>
  concept C = true;                         // error: local concepts are not allowed

  return;                                   // OK
}
\end{codeblock}
\end{example}

\pnum
An \grammarterm{empty-declaration} has no effect.

\pnum
Except where otherwise specified, the meaning of an \grammarterm{attribute-declaration}
is \impldef{meaning of attribute declaration}.

\rSec1[dcl.spec]{Specifiers}%

\rSec2[dcl.spec.general]{General}%
\indextext{specifier|(}

\pnum
\indextext{specifier!declaration}%
The specifiers that can be used in a declaration are
\begin{bnf}
\nontermdef{decl-specifier}\br
    storage-class-specifier\br
    defining-type-specifier\br
    function-specifier\br
    \keyword{friend}\br
    \keyword{typedef}\br
    \keyword{constexpr}\br
    \keyword{consteval}\br
    \keyword{constinit}\br
    \keyword{inline}
\end{bnf}

\begin{bnf}
\nontermdef{decl-specifier-seq}\br
    decl-specifier \opt{attribute-specifier-seq}\br
    decl-specifier decl-specifier-seq
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{decl-specifier-seq}
appertains to the type determined by the preceding
\grammarterm{decl-specifier}{s}\iref{dcl.meaning}. The \grammarterm{attribute-specifier-seq}
affects the type only for the declaration it appears in, not other declarations involving the
same type.

\pnum
At most one of each of the \grammarterm{decl-specifier}s
\keyword{friend}, \keyword{typedef}, or \keyword{inline}
shall appear in a \grammarterm{decl-specifier-seq}.
At most one of
the \keyword{constexpr}, \keyword{consteval}, and \keyword{constinit} keywords
shall appear in a \grammarterm{decl-specifier-seq}.

\pnum
\indextext{ambiguity!declaration type}%
If a \grammarterm{type-name} is encountered while parsing a \grammarterm{decl-specifier-seq},
it is interpreted as part of the \grammarterm{decl-specifier-seq} if and only if there is no
previous \grammarterm{defining-type-specifier} other than a \grammarterm{cv-qualifier} in the
\grammarterm{decl-specifier-seq}.
The sequence shall be self-consistent as
described below.
\begin{example}
\begin{codeblock}
typedef char* Pc;
static Pc;                      // error: name missing
\end{codeblock}
Here, the declaration \keyword{static} \tcode{Pc} is ill-formed because no
name was specified for the static variable of type \tcode{Pc}. To get a
variable called \tcode{Pc}, a \grammarterm{type-specifier} (other than
\keyword{const} or \tcode{volatile}) has to be present to indicate that
the \grammarterm{typedef-name} \tcode{Pc} is the name being (re)declared,
rather than being part of the \grammarterm{decl-specifier} sequence. For
another example,
\begin{codeblock}
void f(const Pc);               // \tcode{void f(char* const)} (not \tcode{const char*})
void g(const int Pc);           // \tcode{void g(const int)}
\end{codeblock}
\end{example}

\pnum
\indextext{\idxcode{signed}!typedef@\tcode{typedef} and}%
\indextext{\idxcode{unsigned}!typedef@\tcode{typedef} and}%
\indextext{\idxcode{long}!typedef@\tcode{typedef} and}%
\indextext{\idxcode{short}!typedef@\tcode{typedef} and}%
\begin{note}
Since \tcode{signed}, \tcode{unsigned}, \tcode{long}, and \tcode{short}
by default imply \tcode{int}, a \grammarterm{type-name} appearing after one
of those specifiers is treated as the name being (re)declared.
\begin{example}
\begin{codeblock}
void h(unsigned Pc);            // \tcode{void h(unsigned int)}
void k(unsigned int Pc);        // \tcode{void k(unsigned int)}
\end{codeblock}
\end{example}
\end{note}

\rSec2[dcl.stc]{Storage class specifiers}%
\indextext{specifier!storage class}%
\indextext{declaration!storage class}%
\indextext{\idxcode{static}}%
\indextext{\idxcode{thread_local}}%
\indextext{\idxcode{extern}}%
\indextext{\idxcode{mutable}}

\pnum
The storage class specifiers are
\begin{bnf}
\nontermdef{storage-class-specifier}\br
    \keyword{static}\br
    \keyword{thread_local}\br
    \keyword{extern}\br
    \keyword{mutable}
\end{bnf}

At most one \grammarterm{storage-class-specifier} shall appear in a given
\grammarterm{decl-specifier-seq}, except that \keyword{thread_local} may appear with \keyword{static} or
\keyword{extern}. If \keyword{thread_local} appears in any declaration of
a variable it shall be present in all declarations of that entity. If a
\grammarterm{storage-class-specifier}
appears in a \grammarterm{decl-specifier-seq}, there can be no
\tcode{typedef} specifier in the same \grammarterm{decl-specifier-seq} and
the \grammarterm{init-declarator-list} of the \grammarterm{simple-declaration} or
the \grammarterm{member-declarator-list} of the \grammarterm{member-declaration}
shall not be empty (except for an anonymous union declared in a namespace scope\iref{class.union.anon}).
The \grammarterm{storage-class-specifier} applies to the name declared by each
\grammarterm{init-declarator} in the list and not to any names declared by
other specifiers.
\begin{note}
See \ref{temp.expl.spec} and \ref{temp.explicit} for restrictions
in explicit specializations and explicit instantiations, respectively.
\end{note}

\pnum
\begin{note}
A variable declared without a \grammarterm{storage-class-specifier}
at block scope or declared as a function parameter
has automatic storage duration by default\iref{basic.stc.auto}.
\end{note}

\pnum
The \keyword{thread_local} specifier
indicates that the named entity has thread storage duration\iref{basic.stc.thread}. It
shall be applied only
to the declaration of a variable of namespace or block scope,
to a structured binding declaration\iref{dcl.struct.bind}, or
to the declaration of a static data member.
When \keyword{thread_local} is applied to a variable of block scope the
\grammarterm{storage-class-specifier} \keyword{static} is implied if no other
\grammarterm{storage-class-specifier} appears in the
\grammarterm{decl-specifier-seq}.

\pnum
\indextext{restriction!\idxcode{static}}%
The \keyword{static} specifier shall be applied only
to the declaration of a variable or function,
to a structured binding declaration\iref{dcl.struct.bind}, or
to the declaration of an anonymous union\iref{class.union.anon}.
There can be no
\keyword{static} function declarations within a block, nor any
\keyword{static} function parameters. A \tcode{static} specifier used in
the declaration of a variable declares the variable to have static storage
duration\iref{basic.stc.static}, unless accompanied by the
\keyword{thread_local} specifier, which declares the variable to have thread
storage duration\iref{basic.stc.thread}. A \keyword{static} specifier can be
used in declarations of class members;~\ref{class.static} describes its
effect.
\indextext{\idxcode{static}!linkage of}%
For the linkage of a name declared with a \keyword{static} specifier,
see~\ref{basic.link}.

\pnum
\indextext{restriction!\idxcode{extern}}%
The \keyword{extern} specifier shall be applied only to the declaration of a variable
or function. The \keyword{extern} specifier shall not be used in the
declaration of a class member or function parameter.
\indextext{\idxcode{extern}!linkage of}%
\indextext{consistency!linkage}%
For the linkage of a name declared with an \keyword{extern} specifier,
see~\ref{basic.link}.
\begin{note}
The \keyword{extern} keyword can also be used in
\grammarterm{explicit-instantiation}{s} and
\grammarterm{linkage-specification}{s}, but it is not a
\grammarterm{storage-class-specifier} in such contexts.
\end{note}

\pnum
All declarations for a given entity shall give its name the same linkage.
\begin{note}
The linkage given by some declarations is affected by previous declarations.
Overloads are distinct entities.
\end{note}
\begin{example}
\begin{codeblock}
static char* f();               // \tcode{f()} has internal linkage
char* f()                       // \tcode{f()} still has internal linkage
  { @\commentellip@ }

char* g();                      // \tcode{g()} has external linkage
static char* g()                // error: inconsistent linkage
  { @\commentellip@ }

void h();
inline void h();                // external linkage

inline void l();
void l();                       // external linkage

inline void m();
extern void m();                // external linkage

static void n();
inline void n();                // internal linkage

static int a;                   // \tcode{a} has internal linkage
int a;                          // error: two definitions

static int b;                   // \tcode{b} has internal linkage
extern int b;                   // \tcode{b} still has internal linkage

int c;                          // \tcode{c} has external linkage
static int c;                   // error: inconsistent linkage

extern int d;                   // \tcode{d} has external linkage
static int d;                   // error: inconsistent linkage
\end{codeblock}
\end{example}

\pnum
\indextext{declaration!forward}%
The name of a declared but undefined class can be used in an
\keyword{extern} declaration. Such a declaration can only be used in ways
that do not require a complete class type.
\begin{example}
\begin{codeblock}
struct S;
extern S a;
extern S f();
extern void g(S);

void h() {
  g(a);                         // error: \tcode{S} is incomplete
  f();                          // error: \tcode{S} is incomplete
}
\end{codeblock}
\end{example}

\pnum
The \keyword{mutable} specifier shall appear only in the declaration of
a non-static data member\iref{class.mem}
whose type is neither const-qualified nor a reference type.
\begin{example}
\begin{codeblock}
class X {
  mutable const int* p;         // OK
  mutable int* const q;         // error
};
\end{codeblock}
\end{example}

\pnum
\begin{note}
The \keyword{mutable} specifier on a class data member nullifies a
\keyword{const} specifier applied to the containing class object and
permits modification of the mutable class member even though the rest of
the object is const\iref{basic.type.qualifier,dcl.type.cv}.
\end{note}

\rSec2[dcl.fct.spec]{Function specifiers}%
\indextext{specifier!function}%
\indextext{function|seealso{friend function}}
\indextext{function|seealso{member function}}
\indextext{function|seealso{inline function}}
\indextext{function|seealso{virtual function}}

\pnum
A
\grammarterm{function-specifier}
can be used only in a function declaration.
At most one \grammarterm{explicit-specifier} and
at most one \keyword{virtual} keyword shall appear in
a \grammarterm{decl-specifier-seq}.

\begin{bnf}
\nontermdef{function-specifier}\br
    \keyword{virtual}\br
    explicit-specifier
\end{bnf}

\begin{bnf}
\nontermdef{explicit-specifier}\br
    \keyword{explicit} \terminal{(} constant-expression \terminal{)}\br
    \keyword{explicit}
\end{bnf}

\pnum
\indextext{specifier!\idxcode{virtual}}%
The \keyword{virtual} specifier shall be used only in the initial
declaration of a non-static member function; see~\ref{class.virtual}.

\pnum
\indextext{specifier!\idxcode{explicit}}%
An \grammarterm{explicit-specifier} shall be used only in the declaration of
a constructor or conversion function within its class definition;
see~\ref{class.conv.ctor} and~\ref{class.conv.fct}.

\pnum
In an \grammarterm{explicit-specifier},
the \grammarterm{constant-expression}, if supplied, shall be a
contextually converted constant expression of type \tcode{bool}\iref{expr.const.const}.
The \grammarterm{explicit-specifier} \keyword{explicit}
without a \grammarterm{constant-expression} is equivalent to
the \grammarterm{explicit-specifier} \tcode{explicit(true)}.
If the constant expression evaluates to \tcode{true},
the function is explicit. Otherwise, the function is not explicit.
A \tcode{(} token that follows \keyword{explicit} is parsed as
part of the \grammarterm{explicit-specifier}.
\begin{example}
\begin{codeblock}
struct S {
  explicit(sizeof(char[2])) S(char);    // error: narrowing conversion of value 2 to type \keyword{bool}
  explicit(sizeof(char)) S(bool);       // OK, conversion of value 1 to type \keyword{bool} is non-narrowing
};
\end{codeblock}
\end{example}

\rSec2[dcl.typedef]{The \keyword{typedef} specifier}%
\indextext{specifier!\idxcode{typedef}}

\indextext{declaration!\idxcode{typedef}}%
\indextext{declaration!\idxcode{typedef}|see{alias, type}}%
\pnum
Declarations containing the \grammarterm{decl-specifier} \keyword{typedef}
declare \defnadjx{type}{aliases}{alias}.
The \keyword{typedef} specifier shall not be
combined in a \grammarterm{decl-specifier-seq} with any other kind of
specifier except a \grammarterm{defining-type-specifier}, and it shall not be used in the
\grammarterm{decl-specifier-seq} of a
\grammarterm{parameter-declaration}\iref{dcl.fct} nor in the
\grammarterm{decl-specifier-seq} of a
\grammarterm{function-definition}\iref{dcl.fct.def}.
If a \keyword{typedef} specifier appears in a declaration without a \grammarterm{declarator},
the program is ill-formed.

\begin{bnf}
\nontermdef{typedef-name}\br
    identifier\br
    simple-template-id
\end{bnf}

A name declared with the \keyword{typedef} specifier becomes a
\grammarterm{typedef-name}.
The underlying entity of the type alias is
the type associated with the \grammarterm{identifier}\iref{dcl.decl}
or \grammarterm{simple-template-id}\iref{temp.pre}.
\indextext{equivalence!type}%
A \grammarterm{typedef-name} does not introduce a new type the way a class
declaration\iref{class.name} or enum declaration\iref{dcl.enum} does.
\begin{example}
After
\begin{codeblock}
typedef int MILES, *KLICKSP;
\end{codeblock}
the constructions
\begin{codeblock}
MILES distance;
extern KLICKSP metricp;
\end{codeblock}
are all correct declarations; the type of \tcode{distance} is
\tcode{int} and that of \tcode{metricp} is ``pointer to \tcode{int}''.
\end{example}

\pnum
A type alias can also be declared by an
\grammarterm{alias-declaration}. The \grammarterm{identifier} following the
\tcode{using} keyword is not looked up;
it becomes the \grammarterm{typedef-name} of a type alias
and the optional \grammarterm{attribute-specifier-seq} following the
\grammarterm{identifier} appertains to that type alias.
Such a type alias has the same
semantics as if it were introduced by the \keyword{typedef} specifier.
\begin{example}
\begin{codeblock}
using handler_t = void (*)(int);
extern handler_t ignore;
extern void (*ignore)(int);         // redeclare \tcode{ignore}
template<class T> struct P { };
using cell = P<cell*>;              // error: \tcode{cell} not found\iref{basic.scope.pdecl}
\end{codeblock}
\end{example}
The \grammarterm{defining-type-specifier-seq}
of the \grammarterm{defining-type-id} shall not define
a class or enumeration if the \grammarterm{alias-declaration}
is the \grammarterm{declaration} of a \grammarterm{template-declaration}.

\pnum
\indextext{class name!\idxcode{typedef}}%
A \grammarterm{simple-template-id} is only a \grammarterm{typedef-name}
if its \grammarterm{template-name} names
an alias template or a type template template parameter.
\begin{note}
A \grammarterm{simple-template-id} that names a class template specialization
is a \grammarterm{class-name}\iref{class.name}.
If a \grammarterm{typedef-name} is used to identify the subject of an
\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}, a class
definition\iref{class}, a constructor
declaration\iref{class.ctor}, or a destructor
declaration\iref{class.dtor}, the program is ill-formed.
\end{note}
\begin{example}
\begin{codeblock}
struct S {
  S();
  ~S();
};

typedef struct S T;

S a = T();                      // OK
struct T * p;                   // error
\end{codeblock}
\end{example}

\pnum
\indextext{class name!\idxcode{typedef}}%
\indextext{enum name!\idxcode{typedef}}%
\indextext{class!unnamed}%
An unnamed class or enumeration $C$ defined in a typedef declaration has
the first \grammarterm{typedef-name}
declared by the declaration to be of type $C$
as its \defn{typedef name for linkage purposes}\iref{basic.link}.
\begin{note}
A typedef declaration involving a \grammarterm{lambda-expression}
does not itself define the associated closure type,
and so the closure type is not given a typedef name for linkage purposes.
\end{note}
\begin{example}
\begin{codeblock}
typedef struct { } *ps, S;      // \tcode{S} is the typedef name for linkage purposes
typedef decltype([]{}) C;       // the closure type has no typedef name for linkage purposes
\end{codeblock}
\end{example}

\pnum
An unnamed class with a typedef name for linkage purposes shall not
\begin{itemize}
\item
  declare any members
  other than non-static data members, member enumerations, or member classes,
\item
  have any base classes or default member initializers, or
\item
  contain a \grammarterm{lambda-expression},
\end{itemize}
and all member classes shall also satisfy these requirements (recursively).
\begin{example}
\begin{codeblock}
typedef struct {
  int f() {}
} X;                            // error: struct with typedef name for linkage has member functions
\end{codeblock}
\end{example}

\rSec2[dcl.friend]{The \keyword{friend} specifier}%
\indextext{specifier!\idxcode{friend}}

\pnum
The \keyword{friend} specifier is used to specify access to class members;
see~\ref{class.friend}.

\rSec2[dcl.constexpr]{The \keyword{constexpr} and \keyword{consteval} specifiers}%
\indextext{specifier!\idxcode{constexpr}}
\indextext{specifier!\idxcode{consteval}}

\pnum
The \keyword{constexpr} specifier shall be applied only to
the definition of a variable or variable template,
a structured binding declaration, or
the declaration of a function or function template.
The \keyword{consteval} specifier shall be applied only to
the declaration of a function or function template.
A function or static data member
declared with the \keyword{constexpr} or \keyword{consteval} specifier
on its first declaration
is implicitly an inline function or variable\iref{dcl.inline}.
If any declaration of a function or function template has
a \keyword{constexpr} or \keyword{consteval} specifier,
then all its declarations shall contain the same specifier.
\begin{note}
An explicit specialization can differ from the template declaration
with respect to the \keyword{constexpr} or \keyword{consteval} specifier.
\end{note}
\begin{note}
Function parameters cannot be declared \keyword{constexpr}.
\end{note}
\begin{example}
\begin{codeblock}
constexpr void square(int &x);  // OK, declaration
constexpr int bufsz = 1024;     // OK, definition
constexpr struct pixel {        // error: \tcode{pixel} is a type
  int x;
  int y;
  constexpr pixel(int);         // OK, declaration
};
constexpr pixel::pixel(int a)
  : x(a), y(x)                  // OK, definition
  { square(x); }
constexpr pixel small(2);       // error: \tcode{square} not defined, so \tcode{small(2)}
                                // not constant\iref{expr.const.core} so \keyword{constexpr} not satisfied

constexpr void square(int &x) { // OK, definition
  x *= x;
}
constexpr pixel large(4);       // OK, \tcode{square} defined
int next(constexpr int x) {     // error: not for parameters
     return x + 1;
}
extern constexpr int memsz;     // error: not a definition
\end{codeblock}
\end{example}

\pnum
A \keyword{constexpr} or \keyword{consteval} specifier
used in the declaration of a function
declares that function to be
a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}.
\begin{note}
A function declared with the \keyword{consteval} specifier
is an immediate function\iref{expr.const.imm}.
\end{note}
A destructor, an allocation function, or a deallocation function
shall not be declared with the \keyword{consteval} specifier.

\pnum
\indextext{specifier!\idxcode{constexpr}!function}%
\indextext{constexpr function}%
A function is \defn{constexpr-suitable} if
it is not a coroutine\iref{dcl.fct.def.coroutine}.

Except for instantiated constexpr functions,
non-templated constexpr functions shall be constexpr-suitable.

\begin{example}
\begin{codeblock}
constexpr int square(int x)
  { return x * x; }             // OK
constexpr long long_max()
  { return 2147483647; }        // OK
constexpr int abs(int x) {
  if (x < 0)
    x = -x;
  return x;                     // OK
}
constexpr int constant_non_42(int n) {  // OK
  if (n == 42) {
    static int value = n;
    return value;
  }
  return n;
}
constexpr int uninit() {
  struct { int a; } s;
  return s.a;                   // error: uninitialized read of \tcode{s.a}
}
constexpr int prev(int x)
  { return --x; }               // OK
constexpr int g(int x, int n) { // OK
  int r = 1;
  while (--n > 0) r *= x;
  return r;
}
\end{codeblock}
\end{example}

\pnum
An invocation of a constexpr function in a given context
produces the same result as
an invocation of an equivalent non-constexpr function in the same context
in all respects except that
\begin{itemize}
\item
an invocation of a constexpr function
can appear in a constant expression\iref{expr.const.core} and
\item
copy elision is not performed in a constant expression\iref{class.copy.elision}.
\end{itemize}
\begin{note}
Declaring a function constexpr can change whether an expression
is a constant expression.
This can indirectly cause calls to \tcode{std::is_constant_evaluated}
within an invocation of the function to produce a different value.
\end{note}
\begin{note}
It is possible to write a constexpr function for which
no invocation satisfies the requirements of a core constant expression.
\end{note}

\pnum
The \keyword{constexpr} and \keyword{consteval} specifiers have no
effect on the type of a constexpr function.
\begin{example}
\begin{codeblock}
constexpr int bar(int x, int y)         // OK
    { return x + y + x*y; }
// ...
int bar(int x, int y)                   // error: redefinition of \tcode{bar}
    { return x * 2 + 3 * y; }
\end{codeblock}
\end{example}

\pnum
A \keyword{constexpr} specifier used in an object declaration
declares the object as const.
Such an object
shall have literal type and
shall be initialized.
A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const.init}.
A \keyword{constexpr} variable that is an object,
as well as any temporary to which a \keyword{constexpr} reference is bound,
shall have constant destruction.
\begin{example}
\begin{codeblock}
struct pixel {
  int x, y;
};
constexpr pixel ur = { 1294, 1024 };    // OK
constexpr pixel origin;                 // error: initializer missing

namespace N {
  void f() {
    int x;
    constexpr int& ar = x;              // OK
    static constexpr int& sr = x;       // error: \tcode{x} is not constexpr-representable
                                        // at the point indicated below
  }
  // immediate scope here is that of \tcode{N}
}
\end{codeblock}
\end{example}

\rSec2[dcl.constinit]{The \keyword{constinit} specifier}
\indextext{specifier!\idxcode{constinit}}

\pnum
The \keyword{constinit} specifier shall be applied only
to a declaration of a variable with static or thread storage duration
or to a structured binding declaration\iref{dcl.struct.bind}.
\begin{note}
A structured binding declaration introduces a uniquely named variable,
to which the \tcode{constinit} specifier applies.
\end{note}
If the specifier is applied to any declaration of a variable,
it shall be applied to the initializing declaration.
No diagnostic is required if no \keyword{constinit} declaration
is reachable at the point of the initializing declaration.

\pnum
If a variable declared with the \keyword{constinit} specifier has
dynamic initialization\iref{basic.start.dynamic}, the program is ill-formed,
even if the implementation would perform that initialization as
a static initialization\iref{basic.start.static}.
\begin{note}
The \keyword{constinit} specifier ensures that the variable
is initialized during static initialization.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
const char * g() { return "dynamic initialization"; }
constexpr const char * f(bool p) { return p ? "constant initializer" : g(); }
constinit const char * c = f(true);     // OK
constinit const char * d = f(false);    // error
\end{codeblock}
\end{example}

\rSec2[dcl.inline]{The \keyword{inline} specifier}%
\indextext{specifier!\idxcode{inline}}

\pnum
\indextext{specifier!\idxcode{inline}}%
\indextext{inline function}%
\indextext{inline variable}%
The \keyword{inline} specifier shall be applied only to the declaration
of a function or variable.
The \keyword{inline} specifier shall not appear on a block scope declaration or
on the declaration of a function parameter.
If the \keyword{inline} specifier is used in a friend function declaration, that
declaration shall be a definition or the function shall have previously
been declared inline.

\pnum
A function declaration\iref{dcl.fct,class.mfct,class.friend}
with an \keyword{inline} specifier declares an
\defnadj{inline}{function}.
A variable declaration with an \keyword{inline} specifier declares an
\defnadj{inline}{variable}.
\begin{note}
An inline function or variable
with external or module linkage
can be defined in multiple translation units\iref{basic.def.odr},
but is one entity with one address.
A type or \keyword{static} variable
defined in the body of such a function
is therefore a single entity.
\end{note}
\begin{note}
The \keyword{inline} keyword has no effect on the linkage of a function.
In certain cases, an inline function cannot use names with internal linkage;
see~\ref{basic.link}.
\end{note}

\pnum
The \keyword{inline} specifier indicates to
the implementation that inline substitution of the function body at the
point of call is to be preferred to the usual function call mechanism.
An implementation is not required to perform this inline substitution at
the point of call; however, even if this inline substitution is omitted,
the other rules for inline functions specified in this subclause shall
still be respected.

\pnum
If a definition of a function or variable is reachable
at the point of its
first declaration as inline, the program is ill-formed. If a function or variable
with external or module linkage
is declared inline in one definition domain,
an inline declaration of it shall be reachable
from the end of every definition domain in which it is declared;
no diagnostic is required.
\begin{note}
A call to an inline function or a use of an inline variable can be encountered
before its definition becomes reachable in a translation unit.
\end{note}

\pnum
If an inline function or variable that is attached to a named module
is declared in a definition domain,
it shall be defined in that domain.
\begin{note}
A constexpr function\iref{dcl.constexpr} is implicitly inline.
In the global module, a function defined within a class definition
is implicitly inline\iref{class.mfct,class.friend}.
\end{note}

\rSec2[dcl.type]{Type specifiers}%

\rSec3[dcl.type.general]{General}%
\indextext{specifier!type|see{type specifier}}

\pnum
The type-specifiers are
\indextext{type!\idxcode{const}}%
\indextext{type!\idxcode{volatile}}%
%
\begin{bnf}
\nontermdef{type-specifier}\br
  simple-type-specifier\br
  elaborated-type-specifier\br
  typename-specifier\br
  cv-qualifier
\end{bnf}

\begin{bnf}
\nontermdef{type-specifier-seq}\br
    type-specifier \opt{attribute-specifier-seq}\br
    type-specifier type-specifier-seq
\end{bnf}

\begin{bnf}
\nontermdef{defining-type-specifier}\br
    type-specifier\br
    class-specifier\br
    enum-specifier
\end{bnf}

\begin{bnf}
\nontermdef{defining-type-specifier-seq}\br
  defining-type-specifier \opt{attribute-specifier-seq}\br
  defining-type-specifier defining-type-specifier-seq
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{type-specifier-seq}
or a \grammarterm{defining-type-specifier-seq}
appertains
to the type denoted by the preceding \grammarterm{type-specifier}{s}
or \grammarterm{defining-type-specifier}{s}\iref{dcl.meaning}. The
\grammarterm{attribute-specifier-seq} affects the type only for the declaration it appears in,
not other declarations involving the same type.

\pnum
As a general rule, at most one
\grammarterm{defining-type-specifier}
is allowed in the complete
\grammarterm{decl-specifier-seq} of a \grammarterm{declaration} or in a
\grammarterm{defining-type-specifier-seq},
and at most one
\grammarterm{type-specifier}
is allowed in a
\grammarterm{type-specifier-seq}.
The only exceptions to this rule are the following:
\begin{itemize}
\item \keyword{const} can be combined with any type specifier except itself.

\item \tcode{volatile} can be combined with any type specifier except itself.

\item \tcode{signed} or \tcode{unsigned} can be combined with
\tcode{char}, \tcode{long}, \tcode{short}, or \tcode{int}.

\item \tcode{short} or \tcode{long} can be combined with \tcode{int}.

\item \tcode{long} can be combined with \tcode{double}.

\item \tcode{long} can be combined with \tcode{long}.
\end{itemize}

\pnum
Except in a declaration of a constructor, destructor, or conversion
function, at least one \grammarterm{defining-type-specifier} that is not a
\grammarterm{cv-qualifier} shall appear in a complete
\grammarterm{type-specifier-seq} or a complete
\grammarterm{decl-specifier-seq}.

\pnum
\begin{note}
\grammarterm{enum-specifier}{s},
\grammarterm{class-specifier}{s},
and
\grammarterm{typename-specifier}{s}
are discussed
in
\ref{dcl.enum},
\ref{class},
and
\ref{temp.res}, respectively. The remaining
\grammarterm{type-specifier}{s} are discussed in the rest of \ref{dcl.type}.
\end{note}

\rSec3[dcl.type.cv]{The \fakegrammarterm{cv-qualifier}{s}}%
\indextext{specifier!cv-qualifier}%
\indextext{initialization!\idxcode{const}}%
\indextext{type specifier!\idxcode{const}}%
\indextext{type specifier!\idxcode{volatile}}

\pnum
There are two \grammarterm{cv-qualifier}{s}, \keyword{const} and
\tcode{volatile}. Each \grammarterm{cv-qualifier} shall appear at most once in
a \grammarterm{cv-qualifier-seq}. If a \grammarterm{cv-qualifier} appears in a
\grammarterm{decl-specifier-seq},
the \grammarterm{init-declarator-list} of the \grammarterm{simple-declaration} or
the \grammarterm{member-declarator-list} of the \grammarterm{member-declaration}
shall not be empty.
\begin{note}
\ref{basic.type.qualifier} and \ref{dcl.fct} describe how cv-qualifiers affect object and
function types.
\end{note}
Redundant cv-qualifications are ignored.
\begin{note}
For example,
these could be introduced by typedefs.
\end{note}

\pnum
\begin{note}
Declaring a variable \keyword{const} can affect its linkage\iref{dcl.stc}
and its usability in constant expressions\iref{expr.const.init}. As
described in~\ref{dcl.init}, the definition of an object or subobject
of const-qualified type must specify an initializer or be subject to
default-initialization.
\end{note}

\pnum
A pointer or reference to a cv-qualified type need not actually point or
refer to a cv-qualified object, but it is treated as if it does; a
const-qualified access path cannot be used to modify an object even if
the object referenced is a non-const object and can be modified through
some other access path.
\begin{note}
Cv-qualifiers are supported by the type system so that they cannot be
subverted without casting\iref{expr.const.cast}.
\end{note}

\pnum
\indextext{const object!undefined change to}%
Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a
const object\iref{basic.type.qualifier} during its
lifetime\iref{basic.life} results in undefined behavior.
\begin{example}
\begin{codeblock}
const int ci = 3;                       // cv-qualified (initialized as required)
ci = 4;                                 // error: attempt to modify \keyword{const}

int i = 2;                              // not cv-qualified
const int* cip;                         // pointer to \tcode{const int}
cip = &i;                               // OK, cv-qualified access path to unqualified
*cip = 4;                               // error: attempt to modify through ptr to \keyword{const}

int* ip;
ip = const_cast<int*>(cip);             // cast needed to convert \tcode{const int*} to \tcode{int*}
*ip = 4;                                // defined: \tcode{*ip} points to \tcode{i}, a non-const object

const int* ciq = new const int (3);     // initialized as required
int* iq = const_cast<int*>(ciq);        // cast required
*iq = 4;                                // undefined behavior: modifies a const object
\end{codeblock}
For another example,
\begin{codeblock}
struct X {
  mutable int i;
  int j;
};
struct Y {
  X x;
  Y();
};

const Y y;
y.x.i++;                                // well-formed: \keyword{mutable} member can be modified
y.x.j++;                                // error: const-qualified member modified
Y* p = const_cast<Y*>(&y);              // cast away const-ness of \tcode{y}
p->x.i = 99;                            // well-formed: \keyword{mutable} member can be modified
p->x.j = 99;                            // undefined behavior: modifies a const subobject
\end{codeblock}
\end{example}

\pnum
The semantics of an access through a volatile glvalue are
\impldef{semantics of an access through a volatile glvalue}.
If an attempt is made to access an object defined with a
volatile-qualified type through the use of a non-volatile glvalue,
the behavior is undefined.

\pnum
\indextext{type specifier!\idxcode{volatile}}%
\indextext{\idxcode{volatile}!implementation-defined}%
\begin{note}
\tcode{volatile} is a hint to the implementation to avoid aggressive
optimization involving the object because it is possible for the value of the object
to change by means undetectable by an implementation.
Furthermore, for some implementations, \tcode{volatile} can indicate that
special hardware instructions are needed to access the object.
See~\ref{intro.execution} for detailed semantics. In general, the
semantics of \tcode{volatile} are intended to be the same in \Cpp{} as
they are in C.
\end{note}

\rSec3[dcl.type.simple]{Simple type specifiers}%
\indextext{type specifier!simple}

\pnum
The simple type specifiers are
\begin{bnf}
\nontermdef{simple-type-specifier}\br
    \opt{nested-name-specifier} type-name\br
    nested-name-specifier \keyword{template} simple-template-id\br
    computed-type-specifier\br
    placeholder-type-specifier\br
    \opt{nested-name-specifier} template-name\br
    \keyword{char}\br
    \keyword{char8_t}\br
    \keyword{char16_t}\br
    \keyword{char32_t}\br
    \keyword{wchar_t}\br
    \keyword{bool}\br
    \keyword{short}\br
    \keyword{int}\br
    \keyword{long}\br
    \keyword{signed}\br
    \keyword{unsigned}\br
    \keyword{float}\br
    \keyword{double}\br
    \keyword{void}
\end{bnf}

\begin{bnf}
\nontermdef{type-name}\br
    class-name\br
    enum-name\br
    typedef-name
\end{bnf}

\begin{bnf}
\nontermdef{computed-type-specifier}\br
    decltype-specifier\br
    pack-index-specifier\br
    splice-type-specifier
\end{bnf}

\pnum
\indextext{component name}
The component names of a \grammarterm{simple-type-specifier} are those of its
\grammarterm{nested-name-specifier},
\grammarterm{type-name},
\grammarterm{simple-template-id},
\grammarterm{template-name}, and/or
\grammarterm{type-constraint}
(if it is a \grammarterm{placeholder-type-specifier}).
The component name of a \grammarterm{type-name} is the first name in it.

\pnum
\indextext{type specifier!\idxcode{char}}%
\indextext{type specifier!\idxcode{char8_t}}%
\indextext{type specifier!\idxcode{char16_t}}%
\indextext{type specifier!\idxcode{char32_t}}%
\indextext{type specifier!\idxcode{wchar_t}}%
\indextext{type specifier!\idxcode{bool}}%
\indextext{type specifier!\idxcode{short}}%
\indextext{type specifier!\idxcode{int}}%
\indextext{type specifier!\idxcode{long}}%
\indextext{type specifier!\idxcode{signed}}%
\indextext{type specifier!\idxcode{unsigned}}%
\indextext{type specifier!\idxcode{float}}%
\indextext{type specifier!\idxcode{double}}%
\indextext{type specifier!\idxcode{void}}%
\indextext{\idxgram{type-name}}%
\indextext{\idxgram{lambda-introducer}}%
A \grammarterm{placeholder-type-specifier}
is a placeholder for
a type to be deduced\iref{dcl.spec.auto}.
\indextext{deduction!class template arguments}%
A \grammarterm{type-specifier} is a placeholder for
a deduced class type\iref{dcl.type.class.deduct} if either
\begin{itemize}
\item
it is of the form
\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} or
\item
it is of the form \opt{\keyword{typename}} \grammarterm{splice-specifier} and
the \grammarterm{splice-specifier} designates
a class template or alias template.
\end{itemize}
The \grammarterm{nested-name-specifier} or \grammarterm{splice-specifier},
if any, shall be non-dependent and
the \grammarterm{template-name} or \grammarterm{splice-specifier}
shall designate a deducible template.
A \defnadj{deducible}{template} is
\begin{itemize}
\item
a class template,
\item
a type template template parameter, or
\item
an alias template \tcode{A} whose \grammarterm{defining-type-id} is of the form

\begin{ncsimplebnf}
\opt{\keyword{typename}} \opt{nested-name-specifier} \opt{\keyword{template}} simple-template-id
\end{ncsimplebnf}

where the \grammarterm{nested-name-specifier} (if any) is non-dependent and
the \grammarterm{template-name} of the \grammarterm{simple-template-id}
names a deducible template
other than a type template template parameter of \tcode{A}.
\end{itemize}
\begin{note}
An injected-class-name is never interpreted as a \grammarterm{template-name}
in contexts where class template argument deduction would be performed\iref{temp.local}.
\end{note}
The other
\grammarterm{simple-type-specifier}{s}
specify either a previously-declared type, a type determined from an
expression, or one of the
fundamental types\iref{basic.fundamental}.
\tref{dcl.type.simple}
 summarizes the valid combinations of
\grammarterm{simple-type-specifier}{s}
and the types they specify.

\begin{simpletypetable}
{\grammarterm{simple-type-specifier}{s} and the types they specify}
{dcl.type.simple}
{ll}
\topline
\hdstyle{Specifier(s)}            &   \hdstyle{Type}                  \\ \capsep
\grammarterm{type-name}           & the type named                    \\
\grammarterm{simple-template-id}  & the type as defined in~\ref{temp.names}\\
\grammarterm{decltype-specifier}  & the type as defined in~\ref{dcl.type.decltype}\\
\grammarterm{pack-index-specifier} & the type as defined in~\ref{dcl.type.pack.index}\\
\grammarterm{placeholder-type-specifier}
                                  & the type as defined in~\ref{dcl.spec.auto}\\
\grammarterm{template-name}       & the type as defined in~\ref{dcl.type.class.deduct}\\
\grammarterm{splice-type-specifier} & the type as defined in~\ref{dcl.type.splice}\\
\tcode{char}                      & ``\tcode{char}''                  \\
\tcode{unsigned char}             & ``\tcode{unsigned char}''         \\
\tcode{signed char}               & ``\tcode{signed char}''           \\
\keyword{char8_t}                   & ``\tcode{char8_t}''               \\
\keyword{char16_t}                  & ``\tcode{char16_t}''              \\
\keyword{char32_t}                  & ``\tcode{char32_t}''              \\
\tcode{bool}                      & ``\tcode{bool}''                  \\
\tcode{unsigned}                  & ``\tcode{unsigned int}''          \\
\tcode{unsigned int}              & ``\tcode{unsigned int}''          \\
\tcode{signed}                    & ``\tcode{int}''                   \\
\tcode{signed int}                & ``\tcode{int}''                   \\
\tcode{int}                       & ``\tcode{int}''                   \\
\tcode{unsigned short int}        & ``\tcode{unsigned short int}''    \\
\tcode{unsigned short}            & ``\tcode{unsigned short int}''    \\
\tcode{unsigned long int}         & ``\tcode{unsigned long int}''     \\
\tcode{unsigned long}             & ``\tcode{unsigned long int}''     \\
\tcode{unsigned long long int}    & ``\tcode{unsigned long long int}''\\
\tcode{unsigned long long}        & ``\tcode{unsigned long long int}''\\
\tcode{signed long int}           & ``\tcode{long int}''              \\
\tcode{signed long}               & ``\tcode{long int}''              \\
\tcode{signed long long int}      & ``\tcode{long long int}''         \\
\tcode{signed long long}          & ``\tcode{long long int}''         \\
\tcode{long long int}             & ``\tcode{long long int}''         \\
\tcode{long long}                 & ``\tcode{long long int}''         \\
\tcode{long int}                  & ``\tcode{long int}''              \\
\tcode{long}                      & ``\tcode{long int}''              \\
\tcode{signed short int}          & ``\tcode{short int}''             \\
\tcode{signed short}              & ``\tcode{short int}''             \\
\tcode{short int}                 & ``\tcode{short int}''             \\
\tcode{short}                     & ``\tcode{short int}''             \\
\keyword{wchar_t}                   & ``\tcode{wchar_t}''               \\
\tcode{float}                     & ``\tcode{float}''                 \\
\tcode{double}                    & ``\tcode{double}''                \\
\tcode{long double}               & ``\tcode{long double}''           \\
\keyword{void}                      & ``\tcode{void}''                  \\
\end{simpletypetable}

\pnum
When multiple \grammarterm{simple-type-specifier}{s} are allowed, they can be
freely intermixed with other \grammarterm{decl-specifier}{s} in any order.
\begin{note}
It is \impldef{signedness of \tcode{char}} whether objects of \tcode{char} type are
represented as signed or unsigned quantities. The \tcode{signed} specifier
forces \tcode{char} objects to be signed; it is redundant in other contexts.
\end{note}

\rSec3[dcl.type.pack.index]{Pack indexing specifier}

\begin{bnf}
\nontermdef{pack-index-specifier}\br
    typedef-name \terminal{...} \terminal{[} constant-expression \terminal{]}
\end{bnf}

\pnum
The \grammarterm{typedef-name} $P$ in a \grammarterm{pack-index-specifier}
shall be an \grammarterm{identifier} that denotes a pack.

\pnum
The \grammarterm{constant-expression} shall be
a converted constant expression\iref{expr.const.const} of type \tcode{std::size_t}
whose value $V$, termed the index,
is such that $0 \le V < \tcode{sizeof...($P$)}$.

\pnum
A \grammarterm{pack-index-specifier} is a pack expansion\iref{temp.variadic}.

\pnum
\begin{note}
The \grammarterm{pack-index-specifier} denotes
the type of the $V^\text{th}$ element of the pack.
\end{note}

\rSec3[dcl.type.elab]{Elaborated type specifiers}%
\indextext{type specifier!elaborated}%
\indextext{\idxcode{typename}}%
\indextext{type specifier!\idxcode{enum}}

\begin{bnf}
\nontermdef{elaborated-type-specifier}\br
    class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br
    class-key simple-template-id\br
    class-key nested-name-specifier \opt{\keyword{template}} simple-template-id\br
    \keyword{enum} \opt{nested-name-specifier} identifier
\end{bnf}

\pnum
\indextext{component name}%
The component names of an \grammarterm{elaborated-type-specifier} are
its \grammarterm{identifier} (if any) and
those of its \grammarterm{nested-name-specifier} and
\grammarterm{simple-template-id} (if any).

\pnum
\indextext{class name!elaborated}%
\indextext{name!elaborated!\idxcode{enum}}%
If an \grammarterm{elaborated-type-specifier} is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization\iref{temp.expl.spec},
a partial specialization\iref{temp.spec.partial},
an explicit
instantiation\iref{temp.explicit}, or it has one of the following
forms:

\begin{ncsimplebnf}
class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br
class-key \opt{attribute-specifier-seq} simple-template-id \terminal{;}
\end{ncsimplebnf}

In the first case,
the \grammarterm{elaborated-type-specifier} declares
the \grammarterm{identifier} as a \grammarterm{class-name}.
The second case shall appear only
in an \grammarterm{explicit-specialization}\iref{temp.expl.spec} or
in a \grammarterm{template-declaration}
(where it declares a partial specialization).
The \grammarterm{attribute-specifier-seq}, if any, appertains
to the class or template being declared.

\pnum
Otherwise, an \grammarterm{elaborated-type-specifier} $E$ shall not have
an \grammarterm{attribute-specifier-seq}.
If $E$ contains an \grammarterm{identifier}
but no \grammarterm{nested-name-specifier} and
(unqualified) lookup for the \grammarterm{identifier} finds nothing,
$E$ shall not be introduced by the \keyword{enum} keyword and
declares the \grammarterm{identifier} as a \grammarterm{class-name}.
The target scope of $E$ is the nearest enclosing namespace or block scope.

\pnum
A \grammarterm{friend-type-specifier}
that is an \grammarterm{elaborated-type-specifier}
shall have one of the following forms:
\begin{ncsimplebnf}
class-key \opt{nested-name-specifier} identifier\br
class-key simple-template-id\br
class-key nested-name-specifier \opt{\keyword{template}} simple-template-id
\end{ncsimplebnf}
Any unqualified lookup for the \grammarterm{identifier} (in the first case)
does not consider scopes that contain
the nearest enclosing namespace or block scope; no name is bound.
\begin{note}
A \grammarterm{using-directive} in the target scope is ignored
if it refers to a namespace not contained by that scope.
\end{note}

\pnum
\begin{note}
\ref{basic.lookup.elab} describes how name lookup proceeds
in an \grammarterm{elaborated-type-specifier}.
An \grammarterm{elaborated-type-specifier} can be used to refer to
a previously declared \grammarterm{class-name} or \grammarterm{enum-name}
even if the name has been hidden by a non-type declaration.
\end{note}

\pnum
If the \grammarterm{identifier} or \grammarterm{simple-template-id}
in an \grammarterm{elaborated-type-specifier}
resolves to a \grammarterm{class-name} or
\grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier}
introduces it into the declaration the same way a
\grammarterm{simple-type-specifier} introduces
its \grammarterm{type-name}\iref{dcl.type.simple}.
If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a
\grammarterm{typedef-name}\iref{dcl.typedef,temp.names},
the \grammarterm{elaborated-type-specifier} is ill-formed.
\begin{note}
This implies that, within a class template with a template
\grammarterm{type-parameter} \tcode{T}, the declaration
\begin{codeblock}
friend class T;
\end{codeblock}
is ill-formed. However, the similar declaration \tcode{friend T;} is well-formed\iref{class.friend}.
\end{note}

\pnum
The \grammarterm{class-key} or \keyword{enum} keyword
present in an
\grammarterm{elaborated-type-specifier} shall agree in kind with the
declaration to which the name in the
\grammarterm{elaborated-type-specifier} refers. This rule also applies to
the form of \grammarterm{elaborated-type-specifier} that declares a
\grammarterm{class-name} or friend class since it can be construed
as referring to the definition of the class. Thus, in any
\grammarterm{elaborated-type-specifier}, the \keyword{enum} keyword
shall be
used to refer to an enumeration\iref{dcl.enum}, the \keyword{union}
\grammarterm{class-key} shall be used to refer to a union\iref{class.union},
and either the \keyword{class} or \keyword{struct}
\grammarterm{class-key} shall be used to refer to a non-union class\iref{class.pre}.
\begin{example}
\begin{codeblock}
enum class E { a, b };
enum E x = E::a;                // OK
struct S { } s;
class S* p = &s;                // OK
\end{codeblock}
\end{example}

\rSec3[dcl.type.decltype]{Decltype specifiers}%
\indextext{type specifier!\idxcode{decltype}}%

\begin{bnf}
\nontermdef{decltype-specifier}\br
  \keyword{decltype} \terminal{(} expression \terminal{)}
\end{bnf}

\pnum
\indextext{type specifier!\idxcode{decltype}}%
For an expression $E$, the type denoted by \tcode{decltype($E$)} is defined as follows:
\begin{itemize}
\item if $E$ is an unparenthesized \grammarterm{id-expression}
naming a structured binding\iref{dcl.struct.bind},
\tcode{decltype($E$)} is the referenced type as given in
the specification of the structured binding declaration;

\item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression}
naming a constant template parameter\iref{temp.param},
\tcode{decltype($E$)} is the type of the template parameter
after performing any necessary
type deduction\iref{dcl.spec.auto,dcl.type.class.deduct};

\item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} or
an unparenthesized
class
member access\iref{expr.ref}, \tcode{decltype($E$)} is the
type of the entity named by $E$.
If there is no such entity, the program is ill-formed;

\item otherwise, if $E$ is an unparenthesized \grammarterm{splice-expression},
\tcode{decltype($E$)} is the type of the entity, object, or value
designated by the \grammarterm{splice-specifier} of $E$;

\item otherwise, if $E$ is
an xvalue, \tcode{decltype($E$)} is \tcode{T\&\&}, where \tcode{T} is the type
of $E$;

\item otherwise, if $E$ is an lvalue, \tcode{decltype($E$)}
is \tcode{T\&}, where \tcode{T} is the type of $E$;

\item otherwise, \tcode{decltype($E$)} is the type of $E$.
\end{itemize}

The operand of the \keyword{decltype} specifier is an unevaluated
operand\iref{term.unevaluated.operand}.

\begin{example}
\begin{codeblock}
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // type is \tcode{const int\&\&}
decltype(i) x2;                 // type is \tcode{int}
decltype(a->x) x3;              // type is \tcode{double}
decltype((a->x)) x4 = x3;       // type is \tcode{const double\&}
decltype([:^^x1:]) x5 = 18;     // type is \tcode{const int\&\&}
decltype(([:^^x1:])) x6 = 19;   // type is \tcode{const int\&}

void f() {
  [](auto ...pack) {
    decltype(pack...[0]) x7;    // type is \tcode{int}
    decltype((pack...[0])) x8;  // type is \tcode{int\&}
  }(0);
}
\end{codeblock}
\end{example}
\begin{note}
The rules for determining types involving \tcode{decltype(auto)} are specified
in~\ref{dcl.spec.auto}.
\end{note}

\pnum
If the operand of a \grammarterm{decltype-specifier} is a prvalue
and is not a (possibly parenthesized) immediate invocation\iref{expr.const.imm},
the temporary materialization conversion is not applied\iref{conv.rval}
and no result object is provided for the prvalue.
The type of the prvalue may be incomplete or an abstract class type.
\begin{note}
As a result, storage is not allocated for the prvalue and it is not destroyed.
Thus, a class type is not instantiated
as a result of being the type of a function call in this context.
In this context, the common purpose of
writing the expression is merely to refer to its type. In that sense, a
\grammarterm{decltype-specifier} is analogous to a use of a \grammarterm{typedef-name},
so the usual reasons for requiring a complete type do not apply. In particular,
it is not necessary to allocate storage for a temporary object or to enforce the
semantic constraints associated with invoking the type's destructor.
\end{note}
\begin{note}
Unlike the preceding rule, parentheses have no special meaning in this context.
\end{note}
\begin{example}
\begin{codeblock}
template<class T> struct A { ~A() = delete; };
template<class T> auto h()
  -> A<T>;
template<class T> auto i(T)     // identity
  -> T;
template<class T> auto f(T)     // \#1
  -> decltype(i(h<T>()));       // forces completion of \tcode{A<T>} and implicitly uses \tcode{A<T>::\~{}A()}
                                // for the temporary introduced by the use of \tcode{h()}.
                                // (A temporary is not introduced as a result of the use of \tcode{i()}.)
template<class T> auto f(T)     // \#2
  -> void;
auto g() -> void {
  f(42);                        // OK, calls \#2. (\#1 is not a viable candidate: type deduction
                                // fails\iref{temp.deduct} because \tcode{A<int>::\~{}A()} is implicitly used in its
                                // \grammarterm{decltype-specifier})
}
template<class T> auto q(T)
  -> decltype((h<T>()));        // does not force completion of \tcode{A<T>}; \tcode{A<T>::\~{}A()} is not implicitly
                                // used within the context of this \grammarterm{decltype-specifier}
void r() {
  q(42);                        // error: deduction against \tcode{q} succeeds, so overload resolution selects
                                // the specialization ``\tcode{q(T) -> decltype((h<T>()))}'' with \tcode{T}$=$\tcode{int};
                                // the return type is \tcode{A<int>}, so a temporary is introduced and its
                                // destructor is used, so the program is ill-formed
}
\end{codeblock}
\end{example}

\rSec3[dcl.spec.auto]{Placeholder type specifiers}%

\rSec4[dcl.spec.auto.general]{General}%
\indextext{type specifier!\idxcode{auto}}
\indextext{type specifier!\idxcode{decltype(auto)}}%

\begin{bnf}
\nontermdef{placeholder-type-specifier}\br
  \opt{type-constraint} \keyword{auto}\br
  \opt{type-constraint} \keyword{decltype} \terminal{(} \keyword{auto} \terminal{)}
\end{bnf}

\pnum
A \grammarterm{placeholder-type-specifier}
designates a placeholder type that will be replaced later,
typically by deduction
from an initializer.

\pnum
The type of a \grammarterm{parameter-declaration} of a
\begin{itemize}
  \item function declaration\iref{dcl.fct},
  \item \grammarterm{lambda-expression}\iref{expr.prim.lambda}, or
  \item \grammarterm{template-parameter}\iref{temp.param}
\end{itemize}
can be declared using
a \grammarterm{placeholder-type-specifier} of the form
\opt{\grammarterm{type-constraint}} \keyword{auto}.
The placeholder type shall appear
as one of the \grammarterm{decl-specifier}{s} in
the \grammarterm{decl-specifier-seq} or
as one of the \grammarterm{type-specifier}{s} in
a \grammarterm{trailing-return-type}
that specifies the type that replaces such
a \grammarterm{decl-specifier} (see below);
the placeholder type
is a \defn{generic parameter type placeholder}
of the
function declaration,
\grammarterm{lambda-expression}, or
\grammarterm{template-parameter}, respectively.
\begin{note}
Having a generic parameter type placeholder
signifies that the function is
an abbreviated function template\iref{dcl.fct} or
the lambda is a generic lambda\iref{expr.prim.lambda}.
\end{note}

\pnum
A placeholder type can appear in
the \grammarterm{decl-specifier-seq} for a function declarator
that includes a \grammarterm{trailing-return-type}\iref{dcl.fct}.

\pnum
A placeholder type can appear in
the \grammarterm{decl-specifier-seq} or \grammarterm{type-specifier-seq}
in the declared return type of a function declarator
that declares a function other than a conversion function\iref{class.conv.fct};
the return type of the function is
deduced from non-discarded \tcode{return} statements, if any, in the body
of the function\iref{stmt.if}.

\pnum
The type of a variable declared using a placeholder type is
deduced from its initializer.
This use is allowed
in an initializing declaration\iref{dcl.init} of a variable.
The placeholder type shall appear as one of the
\grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq}
or as one of the
\grammarterm{type-specifier}{s} in a \grammarterm{trailing-return-type}
that specifies the type that replaces such a \grammarterm{decl-specifier};
the \grammarterm{decl-specifier-seq}
shall be followed by one or more
\grammarterm{declarator}{s},
each of which shall
be followed by a non-empty
\grammarterm{initializer}.
\begin{example}
\begin{codeblock}
auto x = 5;                     // OK, \tcode{x} has type \tcode{int}
const auto *v = &x, u = 6;      // OK, \tcode{v} has type \tcode{const int*}, \tcode{u} has type \tcode{const int}
static auto y = 0.0;            // OK, \tcode{y} has type \tcode{double}
auto int r;                     // error: \keyword{auto} is not a \grammarterm{storage-class-specifier}
auto f() -> int;                // OK, \tcode{f} returns \tcode{int}
auto g() { return 0.0; }        // OK, \tcode{g} returns \tcode{double}
auto (*fp)() -> auto = f;       // OK
auto h();                       // OK, \tcode{h}'s return type will be deduced when it is defined
\end{codeblock}
\end{example}
The \keyword{auto} \grammarterm{type-specifier}
can also be used to introduce
a structured binding declaration\iref{dcl.struct.bind}.

\pnum
A placeholder type can also be used
in the \grammarterm{type-specifier-seq} of
the \grammarterm{new-type-id} or
in the \grammarterm{type-id} of a
\grammarterm{new-expression}\iref{expr.new}.
In such a \grammarterm{type-id},
the placeholder type shall appear
as one of the \grammarterm{type-specifier}{s} in
the \grammarterm{type-specifier-seq} or
as one of the \grammarterm{type-specifier}{s} in
a \grammarterm{trailing-return-type}
that specifies the type that replaces such a \grammarterm{type-specifier}.

\pnum
The \tcode{auto} \grammarterm{type-specifier} can also be used
as the \grammarterm{simple-type-specifier}
in an explicit type conversion (functional notation)\iref{expr.type.conv}.

\pnum
A program that uses a placeholder type in a context not
explicitly allowed in \ref{dcl.spec.auto} is ill-formed.

\pnum
If the \grammarterm{init-declarator-list} contains more than one
\grammarterm{init-declarator}, they shall all form declarations of
variables. The type of each declared variable is determined
by placeholder type deduction\iref{dcl.type.auto.deduct},
and if the type that replaces the placeholder type is not the
same in each deduction, the program is ill-formed.

\begin{example}
\begin{codeblock}
auto x = 5, *y = &x;            // OK, \keyword{auto} is \tcode{int}
auto a = 5, b = { 1, 2 };       // error: different types for \keyword{auto}
\end{codeblock}
\end{example}

\pnum
If a function with a declared return type that contains a placeholder type has
multiple non-discarded \tcode{return} statements, the return type is deduced for each
such \tcode{return} statement. If the type deduced is not the same in each
deduction, the program is ill-formed.

\pnum
If a function with a declared return type that uses a placeholder type has no
non-discarded \tcode{return} statements, the return type is deduced as though from a
\tcode{return} statement with no operand at the closing brace of the function
body.
\begin{example}
\begin{codeblock}
auto  f() { }                   // OK, return type is \keyword{void}
auto* g() { }                   // error: cannot deduce \tcode{auto*} from \tcode{void()}
\end{codeblock}
\end{example}

\pnum
An exported function
with a declared return type that uses a placeholder type
shall be defined in the translation unit
containing its exported declaration,
outside the \grammarterm{private-module-fragment} (if any).
\begin{note}
The deduced return type cannot have
a name with internal linkage\iref{basic.link}.
\end{note}

\pnum
If a variable or function with an undeduced placeholder type is named by an
expression\iref{basic.def.odr}, the program is ill-formed.  Once a
non-discarded \tcode{return} statement has been seen in a function, however, the return type deduced
from that statement can be used in the rest of the function, including in other
\tcode{return} statements.
\begin{example}
\begin{codeblock}
auto n = n;                     // error: \tcode{n}'s initializer refers to \tcode{n}
auto f();
void g() { &f; }                // error: \tcode{f}'s return type is unknown
auto sum(int i) {
  if (i == 1)
    return i;                   // \tcode{sum}'s return type is \tcode{int}
  else
    return sum(i-1)+i;          // OK, \tcode{sum}'s return type has been deduced
}
\end{codeblock}
\end{example}

\pnum
A result binding never has
an undeduced placeholder type\iref{dcl.contract.res}.
\begin{example}
\begin{codeblock}
auto f()
  post(r : r == 7)  // OK
{
  return 7;
}
\end{codeblock}
\end{example}


\pnum
Return type deduction for a templated
function with a placeholder in its
declared type occurs when the definition is instantiated even if the function
body contains a \tcode{return} statement with a non-type-dependent operand.
\begin{note}
Therefore, any use of a specialization of the function template will
cause an implicit instantiation. Any errors that arise from this instantiation
are not in the immediate context of the function type and can result in the
program being ill-formed\iref{temp.deduct}.
\end{note}
\begin{example}
\begin{codeblock}
template <class T> auto f(T t) { return t; }    // return type deduced at instantiation time
typedef decltype(f(1)) fint_t;                  // instantiates \tcode{f<int>} to deduce return type
template<class T> auto f(T* t) { return *t; }
void g() { int (*p)(int*) = &f; }               // instantiates both \tcode{f}s to determine return types,
                                                // chooses second
\end{codeblock}
\end{example}

\pnum
If a function or function template $F$ has
a declared return type that uses a placeholder type,
redeclarations or specializations of $F$ shall use that
placeholder type, not a deduced type;
otherwise, they shall not use a placeholder type.
\begin{example}
\begin{codeblock}
auto f();
auto f() { return 42; }                         // return type is \tcode{int}
auto f();                                       // OK
int f();                                        // error: \keyword{auto} and \tcode{int} don't match
decltype(auto) f();                             // error: \keyword{auto} and \tcode{decltype(auto)} don't match

template <typename T> auto g(T t) { return t; } // \#1
template auto g(int);                           // OK, return type is \tcode{int}
template char g(char);                          // error: no matching template
template<> auto g(double);                      // OK, forward declaration with unknown return type

template <class T> T g(T t) { return t; }       // OK, not functionally equivalent to \#1
template char g(char);                          // OK, now there is a matching template
template auto g(float);                         // still matches \#1

void h() { return g(42); }                      // error: ambiguous

template <typename T> struct A {
  friend T frf(T);
};
auto frf(int i) { return i; }                   // not a friend of \tcode{A<int>}
extern int v;
auto v = 17;                                    // OK, redeclares \tcode{v}
struct S {
  static int i;
};
auto S::i = 23;                                 // OK
\end{codeblock}
\end{example}

\pnum
A function declared with a return type that uses a placeholder type shall not
be \keyword{virtual}\iref{class.virtual}.

\pnum
A function declared with a return type that uses a placeholder type shall not
be a coroutine\iref{dcl.fct.def.coroutine}.

\pnum
An explicit instantiation declaration\iref{temp.explicit} does not cause the
instantiation of an entity declared using a placeholder type, but it also does
not prevent that entity from being instantiated as needed to determine its
type.
\begin{example}
\begin{codeblock}
template <typename T> auto f(T t) { return t; }
extern template auto f(int);    // does not instantiate \tcode{f<int>}
int (*p)(int) = f;              // instantiates \tcode{f<int>} to determine its return type, but an explicit
                                // instantiation definition is still required somewhere in the program
\end{codeblock}
\end{example}

\rSec4[dcl.type.auto.deduct]{Placeholder type deduction}
\indextext{deduction!placeholder type}%

\pnum
\defnx{Placeholder type deduction}{placeholder type deduction}
is the process by which
a type containing a placeholder type
is replaced by a deduced type.

\pnum
A type \tcode{T} containing a placeholder type,
and a corresponding \grammarterm{initializer-clause} $E$,
are determined as follows:
\begin{itemize}
\item
For a non-discarded \tcode{return} statement that occurs
in a function declared with a return type
that contains a placeholder type,
\tcode{T} is the declared return type.
\begin{itemize}
\item
If the \tcode{return} statement has no operand,
then $E$ is \tcode{void()}.
\item
If the operand is a \grammarterm{braced-init-list}\iref{dcl.init.list},
the program is ill-formed.
\item
If the operand is an \grammarterm{expression} $X$
that is not an \grammarterm{assignment-expression},
$E$ is \tcode{($X$)}.
\begin{note}
A comma expression\iref{expr.comma} is not
an \grammarterm{assignment-expression}.
\end{note}
\item
Otherwise, $E$ is the operand of the \tcode{return} statement.
\end{itemize}
If $E$ has type \keyword{void},
\tcode{T} shall be either
\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)} or
\cv{}~\opt{\grammarterm{type-constraint}} \keyword{auto}.
\item
For a variable declared with a type
that contains a placeholder type,
\tcode{T} is the declared type of the variable.
\begin{itemize}
\item
If the initializer of the variable is a \grammarterm{brace-or-equal-initializer}
of the form \tcode{= \grammarterm{initializer-clause}},
$E$ is the \grammarterm{initializer-clause}.
\item
If the initializer is a \grammarterm{braced-init-list},
it shall consist of a single brace-enclosed \grammarterm{assignment-expression}
and $E$ is the \grammarterm{assignment-expression}.
\item
If the initializer is a parenthesized \grammarterm{expression-list},
the \grammarterm{expression-list} shall be
a single \grammarterm{assignment-expression}
and $E$ is the \grammarterm{assignment-expression}.
\end{itemize}
\item
For an explicit type conversion\iref{expr.type.conv},
\tcode{T} is the specified type, which shall be \keyword{auto}.
\begin{itemize}
\item
If the initializer is a \grammarterm{braced-init-list},
it shall consist of a single brace-enclosed \grammarterm{assignment-expression}
and $E$ is the \grammarterm{assignment-expression}.
\item
If the initializer is a parenthesized \grammarterm{expression-list},
the \grammarterm{expression-list} shall be
a single \grammarterm{assignment-expression}
and $E$ is the \grammarterm{assignment-expression}.
\end{itemize}
\item
For a constant template parameter declared with a type
that contains a placeholder type,
\tcode{T} is the declared type of the constant template parameter
and $E$ is the corresponding template argument.
\end{itemize}

\tcode{T} shall not be an array type.

\pnum
If the \grammarterm{placeholder-type-specifier} is of the form
\opt{\grammarterm{type-constraint}} \keyword{auto},
the deduced type
$\mathtt{T}'$ replacing \tcode{T}
is determined using the rules for template argument deduction.
If the initialization is copy-list-initialization,
a declaration of \tcode{std::initializer_list}
shall precede\iref{basic.lookup.general}
the \grammarterm{placeholder-type-specifier}.
Obtain \tcode{P} from
\tcode{T} by replacing the occurrence of
\opt{\grammarterm{type-constraint}} \keyword{auto} either with
a new invented type template parameter \tcode{U} or,
if the initialization is copy-list-initialization, with
\tcode{std::initializer_list<U>}.
If $E$ is a value synthesized for a constant template parameter
of type \tcode{decltype(auto)}\iref{temp.func.order},
the declaration is ill-formed.
Otherwise, deduce a value for \tcode{U} using the rules
of template argument deduction from a function call\iref{temp.deduct.call},
where \tcode{P} is a
function template parameter type and
the corresponding argument is $E$.
If the deduction fails, the declaration is ill-formed.
Otherwise, $\mathtt{T}'$ is obtained by
substituting the deduced \tcode{U} into \tcode{P}.
\begin{example}
\begin{codeblock}
auto x1 = { 1, 2 };             // \tcode{decltype(x1)} is \tcode{std::initializer_list<int>}
auto x2 = { 1, 2.0 };           // error: cannot deduce element type
auto x3{ 1, 2 };                // error: not a single element
auto x4 = { 3 };                // \tcode{decltype(x4)} is \tcode{std::initializer_list<int>}
auto x5{ 3 };                   // \tcode{decltype(x5)} is \tcode{int}
\end{codeblock}
\end{example}

\begin{example}
\begin{codeblock}
const auto &i = expr;
\end{codeblock}
The type of \tcode{i} is the deduced type of the parameter \tcode{u} in
the call \tcode{f(expr)} of the following invented function template:
\begin{codeblock}
template <class U> void f(const U& u);
\end{codeblock}
\end{example}

\pnum
If the \grammarterm{placeholder-type-specifier} is of the form
\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)},
\tcode{T} shall be the
placeholder alone. The type deduced for \tcode{T} is
determined as described in~\ref{dcl.type.decltype}, as though
$E$ had
been the operand of the \keyword{decltype}.
\begin{example}
\begin{codeblock}
int i;
int&& f();
auto           x2a(i);          // \tcode{decltype(x2a)} is \tcode{int}
decltype(auto) x2d(i);          // \tcode{decltype(x2d)} is \tcode{int}
auto           x3a = i;         // \tcode{decltype(x3a)} is \tcode{int}
decltype(auto) x3d = i;         // \tcode{decltype(x3d)} is \tcode{int}
auto           x4a = (i);       // \tcode{decltype(x4a)} is \tcode{int}
decltype(auto) x4d = (i);       // \tcode{decltype(x4d)} is \tcode{int\&}
auto           x5a = f();       // \tcode{decltype(x5a)} is \tcode{int}
decltype(auto) x5d = f();       // \tcode{decltype(x5d)} is \tcode{int\&\&}
auto           x6a = { 1, 2 };  // \tcode{decltype(x6a)} is \tcode{std::initializer_list<int>}
decltype(auto) x6d = { 1, 2 };  // error: \tcode{\{ 1, 2 \}} is not an expression
auto          *x7a = &i;        // \tcode{decltype(x7a)} is \tcode{int*}
decltype(auto)*x7d = &i;        // error: declared type is not plain \tcode{decltype(auto)}
auto f1(int x) -> decltype((x)) { return (x); }         // return type is \tcode{int\&}
auto f2(int x) -> decltype(auto) { return (x); }        // return type is \tcode{int\&\&}
\end{codeblock}
\end{example}

\pnum
For a \grammarterm{placeholder-type-specifier}
with a \grammarterm{type-constraint},
the immediately-declared constraint\iref{temp.param}
of the \grammarterm{type-constraint} for the type deduced for the placeholder
shall be satisfied.

\rSec3[dcl.type.class.deduct]{Deduced class template specialization types}
\indextext{deduction!class template arguments}%

\pnum
If a placeholder for a deduced class type
appears as a \grammarterm{decl-specifier}
in the \grammarterm{decl-specifier-seq}
of an initializing declaration\iref{dcl.init} of a variable,
the declared type of the variable shall be \cv{}~\tcode{T},
where \tcode{T} is the placeholder.
\begin{example}
\begin{codeblock}
template <class ...T> struct A {
  A(T...) {}
};
A x[29]{};          // error: no declarator operators allowed
const A& y{};       // error: no declarator operators allowed
\end{codeblock}
\end{example}
The placeholder is replaced by the return type
of the function selected by overload resolution
for class template deduction\iref{over.match.class.deduct}.
If the \grammarterm{decl-specifier-seq}
is followed by an \grammarterm{init-declarator-list}
or \grammarterm{member-declarator-list}
containing more than one \grammarterm{declarator},
the type that replaces the placeholder shall be the same in each deduction.

\pnum
A placeholder for a deduced class type
can also be used
in the \grammarterm{type-specifier-seq}
in the \grammarterm{new-type-id} or \grammarterm{type-id}
of a \grammarterm{new-expression}\iref{expr.new},
as the \grammarterm{simple-type-specifier}
in an explicit type conversion (functional notation)\iref{expr.type.conv},
or
as the \grammarterm{type-specifier} in the \grammarterm{parameter-declaration}
of a \grammarterm{template-parameter}\iref{temp.param}.
A placeholder for a deduced class type
shall not appear in any other context.

\pnum
\begin{example}
\begin{codeblock}
template<class T> struct container {
    container(T t) {}
    template<class Iter> container(Iter beg, Iter end);
};
template<class Iter>
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;
std::vector<double> v = { @\commentellip@ };

container c(7);                         // OK, deduces \tcode{int} for \tcode{T}
auto d = container(v.begin(), v.end()); // OK, deduces \tcode{double} for \tcode{T}
container e{5, 6};                      // error: \tcode{int} is not an iterator
\end{codeblock}
\end{example}

\rSec3[dcl.type.splice]{Type splicing}

\begin{bnf}
\nontermdef{splice-type-specifier}\br
   \opt{\keyword{typename}} splice-specifier\br
   \opt{\keyword{typename}} splice-specialization-specifier
\end{bnf}

\pnum
A \grammarterm{splice-specifier} or
\grammarterm{splice-specialization-specifier}
immediately followed by \tcode{::}
is never interpreted as part of a \grammarterm{splice-type-specifier}.
A \grammarterm{splice-specifier} or
\grammarterm{splice-specialization-specifier}
not preceded by \keyword{typename}
is only interpreted as a \grammarterm{splice-type-specifier}
within a type-only context\iref{temp.res.general}.
\begin{example}
\begin{codeblock}
template<std::meta::info R> void tfn() {
  typename [:R:]::type m;       // OK, \keyword{typename} applies to the qualified name
}

struct S { using type = int; };
void fn() {
  [:^^S::type:] *var;           // error: \tcode{[:\caret\caret S::type:]} is an expression
  typename [:^^S::type:] *var;  // OK, declares variable with type \tcode{int*}
}

using alias = [:^^S::type:];    // OK, type-only context
\end{codeblock}
\end{example}

\pnum
For a \grammarterm{splice-type-specifier} of the form
\opt{\keyword{typename}} \grammarterm{splice-specifier},
the \grammarterm{splice-specifier} shall designate
a type, a class template, or an alias template.
The \grammarterm{splice-type-specifier} designates
the same entity as the \grammarterm{splice-specifier}.

\pnum
For a \grammarterm{splice-type-specifier} of the form
\opt{\keyword{typename}} \grammarterm{splice-specialization-specifier},
the \grammarterm{splice-specifier} of
the \grammarterm{splice-specialization-specifier}
shall designate a template \tcode{T}
that is either a class template or an alias template.
The \grammarterm{splice-type-specifier} designates
the specialization of \tcode{T} corresponding to
the template argument list of the \grammarterm{splice-specialization-specifier}.
\indextext{specifier|)}%

\rSec1[dcl.decl]{Declarators}%

\rSec2[dcl.decl.general]{General}%
\indextext{declarator|(}

\indextext{initialization!class object|seealso{constructor}}%
\indextext{\idxcode{*}|see{declarator, pointer}}
\indextext{\idxcode{\&}|see{declarator, reference}}%
\indextext{\idxcode{::*}|see{declarator, pointer-to-member}}%
\indextext{\idxcode{[]}|see{declarator, array}}%
\indextext{\idxcode{()}|see{declarator, function}}%

\pnum
A declarator declares a single variable, function, or type, within a declaration.
The
\grammarterm{init-declarator-list}
appearing in a \grammarterm{simple-declaration}
is a comma-separated sequence of declarators,
each of which can have an initializer.

\begin{bnf}
\nontermdef{init-declarator-list}\br
    init-declarator\br
    init-declarator-list \terminal{,} init-declarator
\end{bnf}

\begin{bnf}
\nontermdef{init-declarator}\br
    declarator initializer\br
    declarator \opt{requires-clause} \opt{function-contract-specifier-seq}
\end{bnf}

\pnum
In all contexts, a \grammarterm{declarator} is interpreted as given below.
Where an \grammarterm{abstract-declarator} can be used (or omitted)
in place of a \grammarterm{declarator}\iref{dcl.fct,except.pre},
it is as if a unique identifier were included in
the appropriate place\iref{dcl.name}.
The preceding specifiers indicate
the type, storage duration, linkage, or other properties
of the entity or entities being declared.
Each declarator specifies one entity and
(optionally) names it and/or
modifies the type of the specifiers with operators such as
\tcode{*} (pointer to) and \tcode{()} (function returning).
\begin{note}
An \grammarterm{init-declarator} can also specify an initializer\iref{dcl.init}.
\end{note}

\pnum
Each \grammarterm{init-declarator} of a \grammarterm{simple-declaration}
or \grammarterm{member-declarator} of a \grammarterm{member-declaration}
is analyzed separately as if it were in a
\grammarterm{simple-declaration} or \grammarterm{member-declaration} by itself.
\begin{note}
A declaration with several declarators is usually equivalent to the corresponding
sequence of declarations each with a single declarator. That is,
\begin{codeblock}
T D1, D2, ... Dn;
\end{codeblock}
is usually equivalent to
\begin{codeblock}
T D1; T D2; ... T Dn;
\end{codeblock}
where \tcode{T} is a \grammarterm{decl-specifier-seq}
and each \tcode{Di} is
an \grammarterm{init-declarator} or \grammarterm{member-declarator}.
One exception is when a name introduced by one of the
\grammarterm{declarator}{s} hides a type name used by the
\grammarterm{decl-specifier}{s}, so that when the same
\grammarterm{decl-specifier}{s} are used in a subsequent declaration,
they do not have the same meaning, as in
\begin{codeblock}
struct S { @\commentellip@ };
S S, T;                 // declare two instances of \tcode{struct S}
\end{codeblock}
which is not equivalent to
\begin{codeblock}
struct S { @\commentellip@ };
S S;
S T;                    // error
\end{codeblock}
Another exception is when \tcode{T} is \keyword{auto}\iref{dcl.spec.auto},
for example:
\begin{codeblock}
auto i = 1, j = 2.0;    // error: deduced types for \tcode{i} and \tcode{j} do not match
\end{codeblock}
as opposed to
\begin{codeblock}
auto i = 1;             // OK, \tcode{i} deduced to have type \tcode{int}
auto j = 2.0;           // OK, \tcode{j} deduced to have type \tcode{double}
\end{codeblock}
\end{note}

\pnum
The optional \grammarterm{requires-clause} in an
\grammarterm{init-declarator} or \grammarterm{member-declarator}
shall be present only if the declarator declares a
templated function\iref{temp.pre}.
%
\indextext{trailing requires-clause@trailing \gterm{requires-clause}|see{\gterm{requires-clause}, trailing}}%
When present after a declarator, the \grammarterm{requires-clause}
is called the \defnx{trailing \grammarterm{requires-clause}}{%
\idxgram{requires-clause}!trailing}.
The trailing \grammarterm{requires-clause} introduces the
\grammarterm{constraint-expression} that results from interpreting
its \grammarterm{constraint-logical-or-expression} as a
\grammarterm{constraint-expression}.
%
\begin{example}
\begin{codeblock}
void f1(int a) requires true;               // error: non-templated function
template<typename T>
  auto f2(T a) -> bool requires true;       // OK
template<typename T>
  auto f3(T a) requires true -> bool;       // error: \grammarterm{requires-clause} precedes \grammarterm{trailing-return-type}
void (*pf)() requires true;                 // error: constraint on a variable
void g(int (*)() requires true);            // error: constraint on a \grammarterm{parameter-declaration}

auto* p = new void(*)(char) requires true;  // error: not a function declaration
\end{codeblock}
\end{example}

\pnum
The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func}
in an \grammarterm{init-declarator}
shall be present only if
the \grammarterm{declarator} declares a function.

\pnum
Declarators have the syntax

\begin{bnf}
\nontermdef{declarator}\br
    ptr-declarator\br
    noptr-declarator parameters-and-qualifiers trailing-return-type
\end{bnf}

\begin{bnf}
\nontermdef{ptr-declarator}\br
    noptr-declarator\br
    ptr-operator ptr-declarator
\end{bnf}

\begin{bnf}
\nontermdef{noptr-declarator}\br
    declarator-id \opt{attribute-specifier-seq}\br
    noptr-declarator parameters-and-qualifiers\br
    noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br
    \terminal{(} ptr-declarator \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{parameters-and-qualifiers}\br
    \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br
    \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{trailing-return-type}\br
    \terminal{->} type-id
\end{bnf}

\begin{bnf}
\microtypesetup{protrusion=false}
\nontermdef{ptr-operator}\br
    \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br
    \terminal{\&} \opt{attribute-specifier-seq}\br
    \terminal{\&\&} \opt{attribute-specifier-seq}\br
    nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{cv-qualifier-seq}\br
    cv-qualifier \opt{cv-qualifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{cv-qualifier}\br
    \keyword{const}\br
    \keyword{volatile}
\end{bnf}

\begin{bnf}
\nontermdef{ref-qualifier}\br
    \terminal{\&}\br
    \terminal{\&\&}
\end{bnf}

\begin{bnf}
\nontermdef{declarator-id}\br
    \opt{\terminal{...}} id-expression
\end{bnf}

\rSec2[dcl.name]{Type names}

\pnum
\indextext{type name}%
To specify type conversions explicitly,
\indextext{operator!cast}%
and as an argument of
\tcode{sizeof},
\tcode{alignof},
\keyword{new},
or
\tcode{typeid},
the name of a type shall be specified.
This can be done with a
\grammarterm{type-id} or \grammarterm{new-type-id}\iref{expr.new},
which is syntactically a declaration for a variable or function
of that type that omits the name of the entity.

\begin{bnf}
\nontermdef{type-id}\br
    type-specifier-seq \opt{abstract-declarator}
\end{bnf}

\begin{bnf}
\nontermdef{defining-type-id}\br
    defining-type-specifier-seq \opt{abstract-declarator}
\end{bnf}

\begin{bnf}
\nontermdef{abstract-declarator}\br
    ptr-abstract-declarator\br
    \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br
    abstract-pack-declarator
\end{bnf}

\begin{bnf}
\nontermdef{ptr-abstract-declarator}\br
    noptr-abstract-declarator\br
    ptr-operator \opt{ptr-abstract-declarator}
\end{bnf}

\begin{bnf}
\nontermdef{noptr-abstract-declarator}\br
    \opt{noptr-abstract-declarator} parameters-and-qualifiers\br
    \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br
    \terminal{(} ptr-abstract-declarator \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{abstract-pack-declarator}\br
    noptr-abstract-pack-declarator\br
    ptr-operator abstract-pack-declarator
\end{bnf}

\begin{bnf}
\nontermdef{noptr-abstract-pack-declarator}\br
    noptr-abstract-pack-declarator parameters-and-qualifiers\br
    \terminal{...}
\end{bnf}

It is possible to identify uniquely the location in the
\grammarterm{abstract-declarator}
where the identifier would appear if the construction were a declarator
in a declaration.
The named type is then the same as the type of the
hypothetical identifier.
\begin{example}
\begin{codeblock}
int                 // \tcode{int i}
int *               // \tcode{int *pi}
int *[3]            // \tcode{int *p[3]}
int (*)[3]          // \tcode{int (*p3i)[3]}
int *()             // \tcode{int *f()}
int (*)(double)     // \tcode{int (*pf)(double)}
\end{codeblock}
name respectively the types
``\tcode{int}'',
``pointer to
\tcode{int}'',
``array of 3 pointers to
\tcode{int}'',
``pointer to array of 3
\tcode{int}'',
``function of (no parameters) returning pointer to
\tcode{int}'',
and ``pointer to a function of
(\tcode{double})
returning
\tcode{int}''.
\end{example}

\pnum
\begin{note}
A type can also be named by a \grammarterm{typedef-name},
which is introduced by a typedef declaration
or \grammarterm{alias-declaration}\iref{dcl.typedef}.
\end{note}

\rSec2[dcl.ambig.res]{Ambiguity resolution}%
\indextext{ambiguity!declaration versus cast}%
\indextext{declaration!parentheses in}

\pnum
The ambiguity arising from the similarity between a function-style cast and
a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration.
In that context, the choice is between
an object declaration
with a function-style cast as the initializer and
a declaration involving a function declarator
with a redundant set of parentheses around a parameter name.
Just as for the ambiguities mentioned in~\ref{stmt.ambig},
the resolution is to consider any construct,
such as the potential parameter declaration,
that could possibly be a declaration
to be a declaration.
However, a construct that can syntactically be a \grammarterm{declaration}
whose outermost \grammarterm{declarator}
would match the grammar of a \grammarterm{declarator}
with a \grammarterm{trailing-return-type}
is a declaration only if it starts with \keyword{auto}.
\begin{note}
A declaration can be explicitly disambiguated by adding parentheses
around the argument.
The ambiguity can be avoided by use of copy-initialization or
list-initialization syntax, or by use of a non-function-style cast.
\end{note}
\begin{example}
\begin{codeblock}
struct S {
  S(int);
};
typedef struct BB { int C[2]; } *B, C;

void foo(double a) {
  S v(int(a));                  // function declaration
  S w(int());                   // function declaration
  S x((int(a)));                // object declaration
  S y((int)a);                  // object declaration
  S z = int(a);                 // object declaration
  S a(B()->C);                  // object declaration
  S b(auto()->C);               // function declaration
}
\end{codeblock}
\end{example}

\pnum
An ambiguity can arise from the similarity between a function-style
cast and a
\grammarterm{type-id}.
The resolution is that any construct that could possibly be a
\grammarterm{type-id}
in its syntactic context shall be considered a
\grammarterm{type-id}.
However, a construct that can syntactically be a \grammarterm{type-id}
whose outermost \grammarterm{abstract-declarator}
would match the grammar of an \grammarterm{abstract-declarator}
with a \grammarterm{trailing-return-type}
is considered a \grammarterm{type-id} only if it starts with \keyword{auto}.
\begin{example}
\begin{codeblock}
template <class T> struct X {};
template <int N> struct Y {};
X<int()> a;                     // \grammarterm{type-id}
X<int(1)> b;                    // expression (ill-formed)
Y<int()> c;                     // \grammarterm{type-id} (ill-formed)
Y<int(1)> d;                    // expression

void foo(signed char a) {
  sizeof(int());                // \grammarterm{type-id} (ill-formed)
  sizeof(int(a));               // expression
  sizeof(int(unsigned(a)));     // \grammarterm{type-id} (ill-formed)

  (int())+1;                    // \grammarterm{type-id} (ill-formed)
  (int(a))+1;                   // expression
  (int(unsigned(a)))+1;         // \grammarterm{type-id} (ill-formed)
}

typedef struct BB { int C[2]; } *B, C;
void g() {
  sizeof(B()->C[1]);            // OK, \tcode{\keyword{sizeof}(}expression\tcode{)}
  sizeof(auto()->C[1]);         // error: \keyword{sizeof} of a function returning an array
}
\end{codeblock}
\end{example}

\pnum
Another ambiguity arises in a
\grammarterm{parameter-declaration-clause} when a
\grammarterm{type-name}
is nested in parentheses.
In this case, the choice is between the declaration of a parameter of type
pointer to function and the declaration of a parameter with redundant
parentheses around the
\grammarterm{declarator-id}.
The resolution is to consider the
\grammarterm{type-name}
as a
\grammarterm{simple-type-specifier}
rather than a
\grammarterm{declarator-id}.
\begin{example}
\begin{codeblock}
class C { };
void f(int(C)) { }              // \tcode{void f(int(*fp)(C c)) \{ \}}
                                // not: \tcode{void f(int C) \{ \}}

int g(C);

void foo() {
  f(1);                         // error: cannot convert \tcode{1} to function pointer
  f(g);                         // OK
}
\end{codeblock}

For another example,
\begin{codeblock}
class C { };
void h(int *(C[10]));           // \tcode{void h(int *(*_fp)(C _parm[10]));}
                                // not: \tcode{void h(int *C[10]);}
\end{codeblock}
\end{example}

\rSec2[dcl.meaning]{Meaning of declarators}%

\rSec3[dcl.meaning.general]{General}%
\indextext{declarator!meaning of|(}

\pnum
\indextext{declaration!type}%
A declarator contains exactly one \grammarterm{declarator-id};
it names the entity that is declared.
If the \grammarterm{unqualified-id} occurring in a \grammarterm{declarator-id}
is a \grammarterm{template-id},
the declarator shall appear in the \grammarterm{declaration} of a
\grammarterm{template-declaration}\iref{temp.decls},
\grammarterm{explicit-specialization}\iref{temp.expl.spec}, or
\grammarterm{explicit-instantiation}\iref{temp.explicit}.
\begin{note}
An \grammarterm{unqualified-id} that is not an \grammarterm{identifier}
is used to declare
certain functions\iref{class.conv.fct,class.dtor,over.oper,over.literal}.
\end{note}
The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared.

\pnum
If the declaration is a friend declaration:
\begin{itemize}
\item
The \grammarterm{declarator} does not bind a name.
\item
If the \grammarterm{id-expression} $E$ in
the \grammarterm{declarator-id} of the \grammarterm{declarator} is
a \grammarterm{qualified-id} or a \grammarterm{template-id}:
\begin{itemize}
  \item
If the friend declaration is not a template declaration,
then in the lookup for the terminal name of $E$:
\begin{itemize}
    \item
if the \grammarterm{unqualified-id} in $E$ is a \grammarterm{template-id},
all function declarations are discarded;
    \item
otherwise,
if the \grammarterm{declarator} corresponds\iref{basic.scope.scope} to
any declaration found of a non-template function,
all function template declarations are discarded;
    \item
each remaining function template is replaced with the specialization chosen by
deduction from the friend declaration\iref{temp.deduct.decl} or
discarded if deduction fails.
\end{itemize}
  \item
The \grammarterm{declarator} shall correspond to
one or more declarations found by the lookup;
they shall all have the same target scope, and
the target scope of the \grammarterm{declarator} is that scope.
\end{itemize}
\item
Otherwise, the terminal name of $E$ is not looked up.
The declaration's target scope is the innermost enclosing namespace scope;
if the declaration is contained by a block scope,
the declaration shall correspond to a reachable\iref{module.reach} declaration
that inhabits the innermost block scope.
\end{itemize}

\pnum
Otherwise:
\begin{itemize}
\item
If the \grammarterm{id-expression} in
the \grammarterm{declarator-id} of the \grammarterm{declarator} is
a \grammarterm{qualified-id} $Q$,
let $S$ be its lookup context\iref{basic.lookup.qual};
the declaration shall inhabit a namespace scope.
\item
Otherwise, let $S$ be the entity associated with the scope inhabited by
the \grammarterm{declarator}.
\item
If the \grammarterm{declarator} declares
an explicit instantiation or a partial or explicit specialization,
the \grammarterm{declarator} does not bind a name.
If it declares a class member,
the terminal name of the \grammarterm{declarator-id} is not looked up;
otherwise, only those lookup results that are nominable in $S$
are considered when identifying
any function template specialization being declared\iref{temp.deduct.decl}.
\begin{example}
\begin{codeblock}
namespace N {
  inline namespace O {
    template<class T> void f(T);        // \#1
    template<class T> void g(T) {}
  }
  namespace P {
    template<class T> void f(T*);       // \#2, more specialized than \#1
    template<class> int g;
  }
  using P::f,P::g;
}
template<> void N::f(int*) {}           // OK, \#2 is not nominable
template void N::g(int);                // error: lookup is ambiguous
\end{codeblock}
\end{example}
\item
Otherwise,
the terminal name of the \grammarterm{declarator-id} is not looked up.
If it is a qualified name,
the \grammarterm{declarator} shall correspond to
one or more declarations nominable in $S$;
all the declarations shall have the same target scope and
the target scope of the \grammarterm{declarator} is that scope.
\begin{example}
\begin{codeblock}
namespace Q {
  namespace V {
    void f();
  }
  void V::f() { @\commentellip@ }     // OK
  void V::g() { @\commentellip@ }     // error: \tcode{g()} is not yet a member of \tcode{V}
  namespace V {
    void g();
  }
}

namespace R {
  void Q::V::g() { @\commentellip@ }  // error: \tcode{R} doesn't enclose \tcode{Q}
}
\end{codeblock}
\end{example}
\item
If the declaration inhabits a block scope $S$ and
declares a function\iref{dcl.fct} or uses the \keyword{extern} specifier,
the declaration shall not be attached to a named module\iref{module.unit};
its target scope is the innermost enclosing namespace scope,
but the name is bound in $S$.
\begin{example}
\begin{codeblock}
namespace X {
  void p() {
    q();                        // error: \tcode{q} not yet declared
    extern void q();            // \tcode{q} is a member of namespace \tcode{X}
    extern void r();            // \tcode{r} is a member of namespace \tcode{X}
  }

  void middle() {
    q();                        // error: \tcode{q} not found
  }

  void q() { @\commentellip@ }        // definition of \tcode{X::q}
}

void q() { @\commentellip@ }          // some other, unrelated \tcode{q}
void X::r() { @\commentellip@ }       // error: \tcode{r} cannot be declared by \grammarterm{qualified-id}
\end{codeblock}
\end{example}
\end{itemize}

\pnum
A
\keyword{static},
\keyword{thread_local},
\keyword{extern},
\keyword{mutable},
\keyword{friend},
\keyword{inline},
\keyword{virtual},
\keyword{constexpr},
\keyword{consteval},
\keyword{constinit},
or
\tcode{typedef}
specifier
or an \grammarterm{explicit-specifier}
applies directly to each \grammarterm{declarator-id}
in a \grammarterm{simple-declaration} or \grammarterm{member-declaration};
the type specified for each \grammarterm{declarator-id} depends on
both the \grammarterm{decl-specifier-seq} and its \grammarterm{declarator}.

\pnum
Thus, (for each \grammarterm{declarator}) a declaration has the form
\begin{codeblock}
T D
\end{codeblock}
where
\tcode{T}
is of the form \opt{\grammarterm{attribute-specifier-seq}}
\grammarterm{decl-specifier-seq}
and
\tcode{D}
is a declarator.
Following is a recursive procedure for determining
the type specified for the contained
\grammarterm{declarator-id}
by such a declaration.

\pnum
First, the
\grammarterm{decl-specifier-seq}
determines a type.
In a declaration
\begin{codeblock}
T D
\end{codeblock}
the
\grammarterm{decl-specifier-seq}
\tcode{T}
determines the type
\tcode{T}.
\begin{example}
In the declaration
\begin{codeblock}
int unsigned i;
\end{codeblock}
the type specifiers
\tcode{int}
\tcode{unsigned}
determine the type
``\tcode{unsigned int}''\iref{dcl.type.simple}.
\end{example}

\pnum
In a declaration
\opt{\grammarterm{attribute-specifier-seq}}
\tcode{T}
\tcode{D}
where
\tcode{D}
is an unadorned \grammarterm{declarator-id},
the type of the declared entity is
``\tcode{T}''.

\pnum
In a declaration
\tcode{T}
\tcode{D}
where
\tcode{D}
has the form
\begin{ncsimplebnf}
\terminal{(} \terminal{D1} \terminal{)}
\end{ncsimplebnf}
the type of the contained
\grammarterm{declarator-id}
is the same as that of the contained
\grammarterm{declarator-id}
in the declaration
\begin{codeblock}
T D1
\end{codeblock}
\indextext{declaration!parentheses in}%
Parentheses do not alter the type of the embedded
\grammarterm{declarator-id},
but they can alter the binding of complex declarators.

\rSec3[dcl.ptr]{Pointers}%
\indextext{declarator!pointer}%

\pnum
In a declaration
\tcode{T}
\tcode{D}
where
\tcode{D}
has the form
\begin{ncsimplebnf}
\terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1}
\end{ncsimplebnf}
and the type of the contained \grammarterm{declarator-id} in the declaration
\tcode{T}
\tcode{D1}
is ``\placeholder{derived-declarator-type-list}
\tcode{T}'',
the type of the \grammarterm{declarator-id} in
\tcode{D}
is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to
\tcode{T}''.
\indextext{declaration!pointer}%
\indextext{declaration!constant pointer}%
The
\grammarterm{cv-qualifier}{s}
apply to the pointer and not to the object pointed to.
Similarly, the optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer and not to the object pointed to.

\pnum
\begin{example}
The declarations
\begin{codeblock}
const int ci = 10, *pc = &ci, *const cpc = pc, **ppc;
int i, *p, *const cp = &i;
\end{codeblock}
declare
\tcode{ci},
a constant integer;
\tcode{pc},
a pointer to a constant integer;
\tcode{cpc},
a constant pointer to a constant integer;
\tcode{ppc},
a pointer to a pointer to a constant integer;
\tcode{i},
an integer;
\tcode{p},
a pointer to integer; and
\tcode{cp},
a constant pointer to integer.
The value of
\tcode{ci},
\tcode{cpc},
and
\tcode{cp}
cannot be changed after initialization.
The value of
\tcode{pc}
can be changed, and so can the object pointed to by
\tcode{cp}.
Examples of
some correct operations are
\begin{codeblock}
i = ci;
*cp = ci;
pc++;
pc = cpc;
pc = p;
ppc = &pc;
\end{codeblock}

Examples of ill-formed operations are
\begin{codeblock}
ci = 1;             // error
ci++;               // error
*pc = 2;            // error
cp = &ci;           // error
cpc++;              // error
p = pc;             // error
ppc = &p;           // error
\end{codeblock}

Each is unacceptable because it would either change the value of an object declared
\keyword{const}
or allow it to be changed through a cv-unqualified pointer later, for example:
\begin{codeblock}
*ppc = &ci;         // OK, but would make \tcode{p} point to \tcode{ci} because of previous error
*p = 5;             // clobber \tcode{ci}
\end{codeblock}
See also~\ref{expr.assign} and~\ref{dcl.init}.
\end{example}

\pnum
\begin{note}
Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}.
Forming a function pointer type is ill-formed if the function type has
\grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier};
see~\ref{dcl.fct}.
Since the address of a bit-field\iref{class.bit} cannot be taken,
a pointer can never point to a bit-field.
\end{note}

\rSec3[dcl.ref]{References}%
\indextext{declarator!reference}

\pnum
In a declaration
\tcode{T}
\tcode{D}
where
\tcode{D}
has either of the forms
\begin{ncsimplebnf}
\terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br
\terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1}
\end{ncsimplebnf}
and the type of the contained \grammarterm{declarator-id} in the declaration
\tcode{T}
\tcode{D1}
is ``\placeholder{derived-declarator-type-list}
\tcode{T}'',
the type of the \grammarterm{declarator-id} in
\tcode{D}
is ``\placeholder{derived-declarator-type-list} reference to
\tcode{T}''.
The optional \grammarterm{attribute-specifier-seq} appertains to the reference type.
Cv-qualified references are ill-formed except when the cv-qualifiers
are introduced through the use of a
\grammarterm{typedef-name}\iref{dcl.typedef,temp.param} or
\grammarterm{decltype-specifier}\iref{dcl.type.decltype},
in which case the cv-qualifiers are ignored.
\begin{example}
\begin{codeblock}
typedef int& A;
const A aref = 3;   // error: lvalue reference to non-\keyword{const} initialized with rvalue
\end{codeblock}

The type of
\tcode{aref}
is ``lvalue reference to \tcode{int}'',
not ``lvalue reference to \tcode{const int}''.
\end{example}
\begin{note}
A reference can be thought of as a name of an object.
\end{note}
\indextext{\idxcode{void\&}}%
Forming the type
``reference to \cv{}~\keyword{void}''
is ill-formed.


\pnum
A reference type that is declared using \tcode{\&} is called an
\defn{lvalue reference}, and a reference type that
is declared using \tcode{\&\&} is called an
\defn{rvalue reference}. Lvalue references and
rvalue references are distinct types. Except where explicitly noted, they are
semantically equivalent and commonly referred to as references.

\pnum
\indextext{declaration!reference}%
\indextext{parameter!reference}%
\begin{example}
\begin{codeblock}
void f(double& a) { a += 3.14; }
// ...
double d = 0;
f(d);
\end{codeblock}
declares
\tcode{a}
to be a reference parameter of
\tcode{f}
so the call
\tcode{f(d)}
will add
\tcode{3.14}
to
\tcode{d}.

\begin{codeblock}
int v[20];
// ...
int& g(int i) { return v[i]; }
// ...
g(3) = 7;
\end{codeblock}
declares the function
\tcode{g()}
to return a reference to an integer so
\tcode{g(3)=7}
will assign
\tcode{7}
to the fourth element of the array
\tcode{v}.
For another example,
\begin{codeblock}
struct link {
  link* next;
};

link* first;

void h(link*& p) {  // \tcode{p} is a reference to pointer
  p->next = first;
  first = p;
  p = 0;
}

void k() {
   link* q = new link;
   h(q);
}
\end{codeblock}
declares
\tcode{p}
to be a reference to a pointer to
\tcode{link}
so
\tcode{h(q)}
will leave
\tcode{q}
with the value zero.
See also~\ref{dcl.init.ref}.
\end{example}

\pnum
It is unspecified whether or not
a reference requires storage\iref{basic.stc}.

\pnum
\indextext{restriction!reference}%
There shall be no references to references,
no arrays of references, and no pointers to references.
\indextext{initialization!reference}%
The declaration of a reference shall contain an
\grammarterm{initializer}\iref{dcl.init.ref}
except when the declaration contains an explicit
\keyword{extern}
specifier\iref{dcl.stc},
is a class member\iref{class.mem} declaration within a class definition,
or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}.

\pnum
Attempting to bind a reference to a function where
the converted initializer is a glvalue whose
type is not call-compatible\iref{expr.call}
with the type of the function's definition
results in undefined behavior.
Attempting to bind a reference to an object where
the converted initializer is a glvalue through which
the object is not type-accessible\iref{basic.lval}
results in undefined behavior.
\begin{note}
\indextext{reference!null}%
The object designated by such a glvalue can be
outside its lifetime\iref{basic.life}.
Because a null pointer value or a pointer past the end of an object
does not point to an object,
a reference in a well-defined program cannot refer to such things;
see~\ref{expr.unary.op}.
As described in~\ref{class.bit}, a reference cannot be bound directly
to a bit-field.
\end{note}
The behavior of an evaluation of a reference\iref{expr.prim.id, expr.ref} that
does not happen after\iref{intro.races} the initialization of the reference
is undefined.
\begin{example}
\begin{codeblock}
int &f(int&);
int &g();
extern int &ir3;
int *ip = 0;
int &ir1 = *ip;                 // undefined behavior: null pointer
int &ir2 = f(ir3);              // undefined behavior: \tcode{ir3} not yet initialized
int &ir3 = g();
int &ir4 = f(ir4);              // undefined behavior: \tcode{ir4} used in its own initializer

char x alignas(int);
int &ir5 = *reinterpret_cast<int *>(&x);    // undefined behavior: initializer refers to char object
\end{codeblock}
\end{example}

\pnum
\indextext{reference collapsing}%
If a \grammarterm{typedef-name}\iref{dcl.typedef,temp.param}
or a \grammarterm{decltype-specifier}\iref{dcl.type.decltype} denotes a type \tcode{TR} that
is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv{}~\tcode{TR}''
creates the type ``lvalue reference to \tcode{T}'', while an attempt to create
the type ``rvalue reference to \cv{}~\tcode{TR}'' creates the type \tcode{TR}.
\begin{note}
This rule is known as reference collapsing.
\end{note}
\begin{example}
\begin{codeblock}
int i;
typedef int& LRI;
typedef int&& RRI;

LRI& r1 = i;                    // \tcode{r1} has the type \tcode{int\&}
const LRI& r2 = i;              // \tcode{r2} has the type \tcode{int\&}
const LRI&& r3 = i;             // \tcode{r3} has the type \tcode{int\&}

RRI& r4 = i;                    // \tcode{r4} has the type \tcode{int\&}
RRI&& r5 = 5;                   // \tcode{r5} has the type \tcode{int\&\&}

decltype(r2)& r6 = i;           // \tcode{r6} has the type \tcode{int\&}
decltype(r2)&& r7 = i;          // \tcode{r7} has the type \tcode{int\&}
\end{codeblock}
\end{example}

\pnum
\begin{note}
Forming a reference to function type is ill-formed if the function
type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier};
see~\ref{dcl.fct}.
\end{note}

\rSec3[dcl.mptr]{Pointers to members}%
\indextext{declarator!pointer-to-member}%
\indextext{pointer to member}%

\pnum
\indextext{component name}%
The component names of a \grammarterm{ptr-operator} are
those of its \grammarterm{nested-name-specifier}, if any.

\pnum
In a declaration
\tcode{T}
\tcode{D}
where
\tcode{D}
has the form
\begin{ncsimplebnf}
nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1}
\end{ncsimplebnf}
and the
\grammarterm{nested-name-specifier}
designates a class,
and the type of the contained \grammarterm{declarator-id} in the declaration
\tcode{T}
\tcode{D1}
is ``\placeholder{derived-declarator-type-list}
\tcode{T}'',
the type of the \grammarterm{declarator-id} in
\tcode{D}
is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to member of class
\grammarterm{nested-name-specifier} of type
\tcode{T}''.
The optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the
pointer-to-member.
The \grammarterm{nested-name-specifier} shall not designate an anonymous union.

\pnum
\begin{example}
\begin{codeblock}
struct X {
  void f(int);
  int a;
};
struct Y;

int X::* pmi = &X::a;
void (X::* pmf)(int) = &X::f;
double X::* pmd;
char Y::* pmc;
\end{codeblock}
declares
\tcode{pmi},
\tcode{pmf},
\tcode{pmd}
and
\tcode{pmc}
to be a pointer to a member of
\tcode{X}
of type
\tcode{int},
a pointer to a member of
\tcode{X}
of type
\tcode{void(int)},
a pointer to a member of
\tcode{X}
of type
\tcode{double}
and a pointer to a member of
\tcode{Y}
of type
\tcode{char}
respectively.
The declaration of
\tcode{pmd}
is well-formed even though
\tcode{X}
has no members of type
\tcode{double}.
Similarly, the declaration of
\tcode{pmc}
is well-formed even though
\tcode{Y}
is an incomplete type.
\tcode{pmi}
and
\tcode{pmf}
can be used like this:
\begin{codeblock}
X obj;
// ...
obj.*pmi = 7;       // assign \tcode{7} to an integer member of \tcode{obj}
(obj.*pmf)(7);      // call a function member of \tcode{obj} with the argument \tcode{7}
\end{codeblock}
\end{example}

\pnum
A pointer to member shall not point to a static member
of a class\iref{class.static},
a member with reference type,
or
``\cv{}~\keyword{void}''.

\pnum
\begin{note}
See also~\ref{expr.unary} and~\ref{expr.mptr.oper}.
The type ``pointer to member'' is distinct from the type ``pointer'',
that is, a pointer to member is declared only by the pointer-to-member
declarator syntax, and never by the pointer declarator syntax.
There is no ``reference-to-member'' type in \Cpp{}.
\end{note}

\rSec3[dcl.array]{Arrays}%
\indextext{declarator!array}

\pnum
In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form
\begin{ncsimplebnf}
\terminal{D1} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}
\end{ncsimplebnf}
and the type of the contained \grammarterm{declarator-id}
in the declaration \tcode{T} \tcode{D1}
is ``\placeholder{derived-declarator-type-list} \tcode{T}'',
the type of the \grammarterm{declarator-id} in \tcode{D} is
``\placeholder{derived-declarator-type-list} array of \tcode{N} \tcode{T}''.
The \grammarterm{constant-expression}
shall be a converted constant expression of type \tcode{std::size_t}\iref{expr.const.const}.
\indextext{bound, of array}%
Its value \tcode{N} specifies the \defnx{array bound}{array!bound},
i.e., the number of elements in the array;
\tcode{N} shall be greater than zero.

\pnum
In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form
\begin{ncsimplebnf}
\terminal{D1 [ ]} \opt{attribute-specifier-seq}
\end{ncsimplebnf}
and the type of the contained \grammarterm{declarator-id}
in the declaration \tcode{T} \tcode{D1}
is ``\placeholder{derived-declarator-type-list} \tcode{T}'',
the type of the \grammarterm{declarator-id} in \tcode{D} is
``\placeholder{derived-declarator-type-list} array of unknown bound of \tcode{T}'', except as specified below.

\pnum
\indextext{declaration!array}%
\label{term.array.type}%
A type of the form ``array of \tcode{N} \tcode{U}'' or
``array of unknown bound of \tcode{U}'' is an \defn{array type}.
The optional \grammarterm{attribute-specifier-seq}
appertains to the array type.

\pnum
\tcode{U} is called the array \defn{element type};
this type shall not be
a reference type,
a function type,
an array of unknown bound, or
\cv{}~\keyword{void}.
\begin{note}
An array can be constructed
from one of the fundamental types (except \keyword{void}),
from a pointer,
from a pointer to member,
from a class,
from an enumeration type,
or from an array of known bound.
\end{note}
\begin{example}
\begin{codeblock}
float fa[17], *afp[17];
\end{codeblock}
declares an array of \tcode{float} numbers and
an array of pointers to \tcode{float} numbers.
\end{example}

\pnum
Any type of the form
``\grammarterm{cv-qualifier-seq} array of \tcode{N} \tcode{U}''
is adjusted to
``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}'',
and similarly for ``array of unknown bound of \tcode{U}''.
\begin{example}
\begin{codeblock}
typedef int A[5], AA[2][3];
typedef const A CA;             // type is ``array of 5 \tcode{const int}''
typedef const AA CAA;           // type is ``array of 2 array of 3 \tcode{const int}''
\end{codeblock}
\end{example}
\begin{note}
An ``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}''
has cv-qualified type; see~\ref{basic.type.qualifier}.
\end{note}

\pnum
An object of type ``array of \tcode{N} \tcode{U}'' consists of
a contiguously allocated non-empty set
of \tcode{N} subobjects of type \tcode{U},
known as the \defnx{elements}{array!element} of the array,
and numbered \tcode{0} to \tcode{N-1}.
The element numbered \tcode{0} is termed
the \defnx{first element}{array!first element} of the array.

\pnum
In addition to declarations in which an incomplete object type is allowed,
an array bound may be omitted in some cases in the declaration of a function
parameter\iref{dcl.fct}.
An array bound may also be omitted
when an object (but not a non-static data member) of array type is initialized
and the declarator is followed by
an initializer\iref{dcl.init,class.mem,expr.type.conv,expr.new}.
\indextext{array size!default}%
In these cases, the array bound is calculated
from the number of initial elements (say, \tcode{N})
supplied\iref{dcl.init.aggr},
and the type of the array is ``array of \tcode{N} \tcode{U}''.

\pnum
Furthermore, if there is a reachable declaration of the entity
that specifies a bound and
has the same host scope\iref{basic.scope.scope},
an omitted array bound is taken to
be the same as in that earlier declaration, and similarly for the definition
of a static data member of a class.
\begin{example}
\begin{codeblock}
extern int x[10];
struct S {
  static int y[10];
};

int x[];                // OK, bound is 10
int S::y[];             // OK, bound is 10

void f() {
  extern int x[];
  int i = sizeof(x);    // error: incomplete object type
}

namespace A { extern int z[3]; }
int A::z[] = {};        // OK, defines an array of 3 elements
\end{codeblock}
\end{example}

\pnum
\indextext{declarator!multidimensional array}%
\begin{note}
When several ``array of'' specifications are adjacent,
a multidimensional array type is created;
only the first of the constant expressions
that specify the bounds of the arrays can be omitted.
\begin{example}
\begin{codeblock}
int x3d[3][5][7];
\end{codeblock}
declares an array of three elements,
each of which is an array of five elements,
each of which is an array of seven integers.
The overall array can be viewed as a
three-dimensional array of integers,
with rank $3 \times 5 \times 7$.
Any of the expressions
\tcode{x3d},
\tcode{x3d[i]},
\tcode{x3d[i][j]},
\tcode{x3d[i][j][k]}
can reasonably appear in an expression.
The expression
\tcode{x3d[i]}
is equivalent to
\tcode{*(x3d + i)};
in that expression,
\tcode{x3d}
is subject to the array-to-pointer conversion\iref{conv.array}
and is first converted to
a pointer to a 2-dimensional
array with rank
$5 \times 7$
that points to the first element of \tcode{x3d}.
Then \tcode{i} is added,
which on typical implementations involves multiplying
\tcode{i} by the
length of the object to which the pointer points,
which is \tcode{sizeof(int)}$ \times 5 \times 7$.
The result of the addition and indirection is
an lvalue denoting
the $\tcode{i}^\text{th}$ array element of
\tcode{x3d}
(an array of five arrays of seven integers).
If there is another subscript,
the same argument applies again, so
\tcode{x3d[i][j]} is
an lvalue denoting
the $\tcode{j}^\text{th}$ array element of
the $\tcode{i}^\text{th}$ array element of
\tcode{x3d}
(an array of seven integers), and
\tcode{x3d[i][j][k]} is
an lvalue denoting
the $\tcode{k}^\text{th}$ array element of
the $\tcode{j}^\text{th}$ array element of
the $\tcode{i}^\text{th}$ array element of
\tcode{x3d}
(an integer).
\end{example}
The first subscript in the declaration helps determine
the amount of storage consumed by an array
but plays no other part in subscript calculations.
\end{note}

\pnum
\begin{note}
Conversions affecting expressions of array type are described in~\ref{conv.array}.
\end{note}

\pnum
\begin{note}
The subscript operator can be overloaded for a class\iref{over.sub}.
For the operator's built-in meaning, see \ref{expr.sub}.
\end{note}

\rSec3[dcl.fct]{Functions}%
\indextext{declarator!function|(}

\pnum
\indextext{type!function}%
In a declaration
\tcode{T}
\tcode{D}
where
\tcode{T} may be empty and
\tcode{D}
has the form
\begin{ncsimplebnf}
\terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br
\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \opt{trailing-return-type}
\end{ncsimplebnf}
a \placeholder{derived-declarator-type-list} is determined as follows:
\begin{itemize}
\item
If the \grammarterm{unqualified-id} of the \grammarterm{declarator-id}
is a \grammarterm{conversion-function-id},
the \placeholder{derived-declarator-type-list} is empty.

\item
Otherwise, the \placeholder{derived-declarator-type-list} is as appears in
the type ``\placeholder{derived-declarator-type-list} \tcode{T}''
of the contained
\grammarterm{declarator-id}
in the declaration
\tcode{T}
\tcode{D1}.
\end{itemize}
The declared return type \tcode{U} of the function type
is determined as follows:
\begin{itemize}
\item
If the \grammarterm{trailing-return-type} is present,
\tcode{T} shall be the single \grammarterm{type-specifier} \keyword{auto}, and
\tcode{U} is the type specified by the \grammarterm{trailing-return-type}.

\item
Otherwise, if the declaration declares a conversion function,
see~\ref{class.conv.fct}.

\item
Otherwise, \tcode{U} is \tcode{T}.
\end{itemize}
The type of the
\grammarterm{declarator-id}
in
\tcode{D}
is
``\placeholder{derived-declarator-type-list}
\opt{\keyword{noexcept}}
function of parameter-type-list
\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}}
returning \tcode{U}'', where
\begin{itemize}
\item
the parameter-type-list is derived from
the \grammarterm{parameter-declaration-clause} as described below and
\item
the optional \keyword{noexcept} is present if and only if
the exception specification\iref{except.spec} is non-throwing.
\end{itemize}
Such a type is a \defnadj{function}{type}.
\begin{footnote}
As indicated by syntax, cv-qualifiers are a significant component in function return types.
\end{footnote}
The optional \grammarterm{attribute-specifier-seq}
appertains to the function type.

\pnum
\indextext{declaration!function}%
\begin{bnf}
\nontermdef{parameter-declaration-clause}\br
    \terminal{...}\br
    \opt{parameter-declaration-list}\br
    parameter-declaration-list \terminal{,} \terminal{...}\br
    parameter-declaration-list \terminal{...}
\end{bnf}

\begin{bnf}
\nontermdef{parameter-declaration-list}\br
    parameter-declaration\br
    parameter-declaration-list \terminal{,} parameter-declaration
\end{bnf}

\begin{bnf}
\nontermdef{parameter-declaration}\br
    \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq declarator\br
    \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br
    \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq \opt{abstract-declarator}\br
    \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration}
appertains to the parameter.

\pnum
\indextext{declaration!parameter}%
The
\grammarterm{parameter-declaration-clause}
determines the arguments that can be specified, and their processing, when the function is called.
\begin{note}
\indextext{conversion!argument}%
The
\grammarterm{parameter-declaration-clause}
is used to convert the arguments specified on the function call;
see~\ref{expr.call}.
\end{note}
\indextext{argument list!empty}%
If the
\grammarterm{parameter-declaration-clause}
is empty, the function takes no arguments.
A parameter list consisting of a single unnamed non-object parameter of
non-dependent type \keyword{void} is equivalent to an empty parameter
list.
\indextext{parameter!\idxcode{void}}%
Except for this special case, a parameter shall not have type \cv{}~\keyword{void}.
A parameter with volatile-qualified type is deprecated;
see~\ref{depr.volatile.type}.
If the
\grammarterm{parameter-declaration-clause}
\indextext{argument type!unknown}%
\indextext{\idxcode{...}|see{ellipsis}}%
\indextext{declaration!ellipsis in function}%
\indextext{argument list!variable}%
\indextext{parameter list!variable}%
terminates with an ellipsis or a function parameter
pack\iref{temp.variadic}, the number of arguments shall be equal
to or greater than the number of parameters that do not have a default
argument and are not function parameter packs.
Where syntactically correct and where ``\tcode{...}'' is not
part of an \grammarterm{abstract-declarator},
``\tcode{...}''
is synonymous with
``\tcode{, ...}''.
A \grammarterm{parameter-declaration-clause}
of the form
\grammarterm{parameter-declaration-list} \tcode{...}
is deprecated\iref{depr.ellipsis.comma}.
\begin{example}
The declaration
\begin{codeblock}
int printf(const char*, ...);
\end{codeblock}
declares a function that can be called with varying numbers and types of arguments.

\begin{codeblock}
printf("hello world");
printf("a=%d b=%d", a, b);
\end{codeblock}

However, the first argument must be of a type
that can be converted to a
\keyword{const}
\tcode{char*}.
\end{example}
\begin{note}
The standard header \libheaderref{cstdarg}
contains a mechanism for accessing arguments passed using the ellipsis
(see~\ref{expr.call} and~\ref{support.runtime}).
\end{note}

\pnum
\indextext{type!function}%
The type of a function is determined using the following rules.
The type of each parameter (including function parameter packs) is
determined from its own \grammarterm{parameter-declaration}\iref{dcl.decl}.
After determining the type of each parameter, any parameter
\indextext{array!parameter of type}%
of type ``array of \tcode{T}'' or
\indextext{function!parameter of type}%
of function type \tcode{T}
is adjusted to be ``pointer to \tcode{T}''.
After producing the list of parameter types,
any top-level
\grammarterm{cv-qualifier}{s}
modifying a parameter type are deleted
when forming the function type.
The resulting list of transformed parameter types
and the presence or absence of the ellipsis or a function parameter pack
is the function's
\defn{parameter-type-list}.
\begin{note}
This transformation does not affect the types of the parameters.
For example, \tcode{int(*)(const int p, decltype(p)*)} and
\tcode{int(*)(int, const int*)} are identical types.
\end{note}
\begin{example}
\begin{codeblock}
void f(char*);                  // \#1
void f(char[]) {}               // defines \#1
void f(const char*) {}          // OK, another overload
void f(char *const) {}          // error: redefines \#1

void g(char(*)[2]);             // \#2
void g(char[3][2]) {}           // defines \#2
void g(char[3][3]) {}           // OK, another overload

void h(int x(const int));       // \#3
void h(int (*)(int)) {}         // defines \#3
\end{codeblock}
\end{example}

\pnum
A function with a parameter-type-list that has an ellipsis
is termed a \defnadj{vararg}{function}.

\pnum
An \defn{explicit-object-parameter-declaration} is
a \grammarterm{parameter-declaration} with a \keyword{this} specifier.
An explicit-object-parameter-declaration shall appear only as
the first \grammarterm{parameter-declaration} of
a \grammarterm{parameter-declaration-list} of one of:
\begin{itemize}
\item
a declaration of
a member function or member function template\iref{class.mem}, or
\item
an explicit instantiation\iref{temp.explicit} or
explicit specialization\iref{temp.expl.spec} of
a templated member function, or
\item
a \grammarterm{lambda-declarator}\iref{expr.prim.lambda}.
\end{itemize}
A \grammarterm{member-declarator} with an explicit-object-parameter-declaration
shall not include
a \grammarterm{ref-qualifier} or a \grammarterm{cv-qualifier-seq} and
shall not be declared \keyword{static} or \keyword{virtual}.
\begin{example}
\begin{codeblock}
struct C {
  void f(this C& self);
  template <typename Self> void g(this Self&& self, int);

  void h(this C) const;         // error: \tcode{const} not allowed here
};

void test(C c) {
  c.f();                        // OK, calls \tcode{C::f}
  c.g(42);                      // OK, calls \tcode{C::g<C\&>}
  std::move(c).g(42);           // OK, calls \tcode{C::g<C>}
}
\end{codeblock}
\end{example}

\pnum
A function parameter declared with an explicit-object-parameter-declaration
is an \defnadj{explicit object}{parameter}.
An explicit object parameter shall not be
a function parameter pack\iref{temp.variadic}.
An \defnadj{explicit object}{member function} is a non-static member function
with an explicit object parameter.
An \defnadj{implicit object}{member function} is a non-static member function
without an explicit object parameter.

\pnum
The \defnadj{object}{parameter} of a non-static member function is either
the explicit object parameter or
the implicit object parameter\iref{over.match.funcs}.

\pnum
A \defnadj{non-object}{parameter} is a function parameter
that is not the explicit object parameter.
The \defn{non-object-parameter-type-list} of a member function is
the parameter-type-list of that function with the explicit object parameter,
if any, omitted.
\begin{note}
The non-object-parameter-type-list consists of
the adjusted types of all the non-object parameters.
\end{note}

\pnum
A function type with a \grammarterm{cv-qualifier-seq} or a
\grammarterm{ref-qualifier} (including a type denoted by
\grammarterm{typedef-name}\iref{dcl.typedef,temp.param})
shall appear only as:
\begin{itemize}
\item the function type for a non-static member function,

\item the function type to which a pointer to member refers,

\item the top-level function type of a function typedef declaration
or \grammarterm{alias-declaration},

\item the \grammarterm{type-id} in the default argument of a
\grammarterm{type-parameter}\iref{temp.param},

\item the \grammarterm{type-id} of a \grammarterm{template-argument} for a
\grammarterm{type-parameter}\iref{temp.arg.type}, or

\item the operand of a \grammarterm{reflect-expression}\iref{expr.reflect}.
\end{itemize}
\begin{example}
\begin{codeblock}
typedef int FIC(int) const;
FIC f;                                                  // error: does not declare a member function
struct S {
  FIC f;                                                // OK
};
FIC S::*pm = &S::f;                                     // OK
constexpr std::meta::info yeti = ^^void(int) const &;   // OK
\end{codeblock}
\end{example}

\pnum
The effect of a
\grammarterm{cv-qualifier-seq}
in a function declarator is not the same as
adding cv-qualification on top of the function type.
In the latter case, the cv-qualifiers are ignored.
\begin{note}
A function type that has a \grammarterm{cv-qualifier-seq} is not a
cv-qualified type; there are no cv-qualified function types.
\end{note}
\begin{example}
\begin{codeblock}
typedef void F();
struct S {
  const F f;        // OK, equivalent to: \tcode{void f();}
};
\end{codeblock}
\end{example}

\pnum
The return type, the parameter-type-list, the \grammarterm{ref-qualifier},
the \grammarterm{cv-qualifier-seq}, and
the exception specification,
but not the default arguments\iref{dcl.fct.default}
or the trailing \grammarterm{requires-clause}\iref{dcl.decl},
are part of the function type.
\begin{note}
Function types are checked during the assignments and initializations of
pointers to functions, references to functions, and pointers to member functions.
\end{note}

\pnum
\begin{example}
The declaration
\begin{codeblock}
int fseek(FILE*, long, int);
\end{codeblock}
declares a function taking three arguments of the specified types,
and returning
\tcode{int}\iref{dcl.type}.
\end{example}

\pnum
\indextext{overloading}%
\begin{note}
A single name can be used for several different functions in a single scope;
this is function overloading\iref{over}.
\end{note}

\pnum
\indextext{function return type|see{return type}}%
\indextext{return type}%
The return type shall be a non-array object type, a reference type, or \cv{}~\keyword{void}.
\begin{note}
An array of placeholder type is considered an array type.
\end{note}

\pnum
A volatile-qualified return type is deprecated;
see~\ref{depr.volatile.type}.

\pnum
Types shall not be defined in return or parameter types.

\pnum
\indextext{typedef!function}%
A typedef of function type may be used to declare a function but shall not be
used to define a function\iref{dcl.fct.def}.
\begin{example}
\begin{codeblock}
typedef void F();
F  fv;              // OK, equivalent to \tcode{void fv();}
F  fv { }           // error
void fv() { }       // OK, definition of \tcode{fv}
\end{codeblock}
\end{example}

\pnum
An identifier can optionally be provided as a parameter name;
if present in a function definition\iref{dcl.fct.def}, it names a parameter.
\begin{note}
In particular, parameter names are also optional in function definitions
and names used for a parameter in different declarations and the definition
of a function need not be the same.
\end{note}

\pnum
\begin{example}
The declaration
\begin{codeblock}
int i,
    *pi,
    f(),
    *fpi(int),
    (*pif)(const char*, const char*),
    (*fpif(int))(int);
\end{codeblock}
declares an integer
\tcode{i},
a pointer
\tcode{pi}
to an integer,
a function
\tcode{f}
taking no arguments and returning an integer,
a function
\tcode{fpi}
taking an integer argument and returning a pointer to an integer,
a pointer
\tcode{pif}
to a function which
takes two pointers to constant characters and returns an integer,
a function
\tcode{fpif}
taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer.
It is especially useful to compare
\tcode{fpi}
and
\tcode{pif}.
The binding of
\tcode{*fpi(int)}
is
\tcode{*(fpi(int))},
so the declaration suggests,
and the same construction in an expression
requires, the calling of a function
\tcode{fpi},
and then using indirection through the (pointer) result
to yield an integer.
In the declarator
\tcode{(*pif)(const char*, const char*)},
the extra parentheses are necessary to indicate that indirection through
a pointer to a function yields a function, which is then called.
\end{example}
\begin{note}
Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex.
For example,
the function
\tcode{fpif}
above can be declared
\begin{codeblock}
typedef int  IFUNC(int);
IFUNC*  fpif(int);
\end{codeblock}
or
\begin{codeblock}
auto fpif(int)->int(*)(int);
\end{codeblock}

A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}:
\begin{codeblock}
template <class T, class U> auto add(T t, U u) -> decltype(t + u);
\end{codeblock}
rather than
\begin{codeblock}
template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
\end{codeblock}
\end{note}

\pnum
A \defnadj{non-template}{function} is a function that is not a function template
specialization.
\begin{note}
A function template is not a function.
\end{note}

\pnum
\indextext{abbreviated!template function|see{template, function, abbreviated}}%
An \defnx{abbreviated function template}{template!function!abbreviated}
is a function declaration that has
one or more generic parameter type placeholders\iref{dcl.spec.auto}.
An abbreviated function template is equivalent to
a function template\iref{temp.fct}
whose \grammarterm{template-parameter-list} includes
one invented \grammarterm{type-parameter}
for each generic parameter type placeholder
of the function declaration, in order of appearance.
For a \grammarterm{placeholder-type-specifier} of the form \keyword{auto},
the invented parameter is
an unconstrained \grammarterm{type-parameter}.
For a \grammarterm{placeholder-type-specifier} of the form
\grammarterm{type-constraint} \keyword{auto},
the invented parameter is a \grammarterm{type-parameter} with
that \grammarterm{type-constraint}.
The invented \grammarterm{type-parameter} declares
a template parameter pack
if the corresponding \grammarterm{parameter-declaration}
declares a function parameter pack.
If the placeholder contains \tcode{decltype(auto)},
the program is ill-formed.
The adjusted function parameters of an abbreviated function template
are derived from the \grammarterm{parameter-declaration-clause} by
replacing each occurrence of a placeholder with
the name of the corresponding invented \grammarterm{type-parameter}.
\begin{example}
\begin{codeblock}
template<typename T>     concept C1 = /* ... */;
template<typename T>     concept C2 = /* ... */;
template<typename... Ts> concept C3 = /* ... */;

void g1(const C1 auto*, C2 auto&);
void g2(C1 auto&...);
void g3(C3 auto...);
void g4(C3 auto);
\end{codeblock}
The declarations above are functionally equivalent (but not equivalent) to
their respective declarations below:
\begin{codeblock}
template<C1 T, C2 U> void g1(const T*, U&);
template<C1... Ts>   void g2(Ts&...);
template<C3... Ts>   void g3(Ts...);
template<C3 T>       void g4(T);
\end{codeblock}
Abbreviated function templates can be specialized like all function templates.
\begin{codeblock}
template<> void g1<int>(const int*, const double&); // OK, specialization of \tcode{g1<int, const double>}
\end{codeblock}
\end{example}

\pnum
An abbreviated function template can have a \grammarterm{template-head}.
The invented \grammarterm{type-parameter}{s} are
appended to the \grammarterm{template-parameter-list} after
the explicitly declared \grammarterm{template-parameter}{s}.
\begin{example}
\begin{codeblock}
template<typename> concept C = /* ... */;

template <typename T, C U>
  void g(T x, U y, C auto z);
\end{codeblock}

This is functionally equivalent to each of the following two declarations.
\begin{codeblock}
template<typename T, C U, C W>
  void g(T x, U y, W z);

template<typename T, typename U, typename W>
  requires C<U> && C<W>
  void g(T x, U y, W z);
\end{codeblock}
\end{example}

\pnum
A function declaration at block scope
shall not declare an abbreviated function template.

\pnum
A \grammarterm{declarator-id} or \grammarterm{abstract-declarator}
containing an ellipsis shall only
be used in a \grammarterm{parameter-declaration}.
When it is part of a
\grammarterm{parameter-declaration-clause},
the \grammarterm{parameter-declaration} declares a
function parameter pack\iref{temp.variadic}.
Otherwise, the \grammarterm{parameter-declaration} is part of a
\grammarterm{template-parameter-list} and declares a
template parameter pack; see~\ref{temp.param}.
A function parameter pack is a pack expansion\iref{temp.variadic}.
\begin{example}
\begin{codeblock}
template<typename... T> void f(T (* ...t)(int, int));

int add(int, int);
float subtract(int, int);

void g() {
  f(add, subtract);
}
\end{codeblock}
\end{example}

\pnum
There is a syntactic ambiguity when an ellipsis occurs at the end
of a \grammarterm{parameter-declaration-clause} without a preceding
comma. In this case, the ellipsis is parsed as part of the
\grammarterm{abstract-declarator} if the type of the parameter either names
a template parameter pack that has not been expanded or contains \keyword{auto};
otherwise, it is
parsed as part of the \grammarterm{parameter-declaration-clause}.
\begin{footnote}
One can explicitly disambiguate the parse either by
introducing a comma (so the ellipsis will be parsed as part of the
\grammarterm{parameter-declaration-clause}) or by introducing a name for the
parameter (so the ellipsis will be parsed as part of the
\grammarterm{declarator-id}).
\end{footnote}
\indextext{declarator!function|)}

\rSec3[dcl.fct.default]{Default arguments}%
\indextext{declaration!default argument|(}

\pnum
If an \grammarterm{initializer-clause} is specified in a
\grammarterm{parameter-declaration} that is not a
\grammarterm{template-parameter}\iref{temp.param},
this \grammarterm{initializer-clause} is used as a default argument.
\begin{note}
Default arguments will be used in calls
where trailing arguments are missing\iref{expr.call}.
\end{note}

\pnum
\indextext{argument!example of default}%
\begin{example}
The declaration
\begin{codeblock}
void point(int = 3, int = 4);
\end{codeblock}
declares a function that can be called with zero, one, or two arguments of type
\tcode{int}.
It can be called in any of these ways:
\begin{codeblock}
point(1,2);  point(1);  point();
\end{codeblock}

The last two calls are equivalent to
\tcode{point(1,4)}
and
\tcode{point(3,4)},
respectively.
\end{example}

\pnum
A default argument shall be specified only in the
\grammarterm{parameter-declaration-clause}
of a function declaration
or \grammarterm{lambda-declarator}.
A default argument shall not be specified for
a function parameter pack.
A default argument shall not occur within a
\grammarterm{declarator}
or
\grammarterm{abstract-declarator}
of a
\grammarterm{parameter-declaration}.
\begin{footnote}
This means that default
arguments cannot appear,
for example, in declarations of pointers to functions,
references to functions, or
\tcode{typedef}
declarations.
\end{footnote}

\pnum
For non-template functions, default arguments can be added in later
declarations of a
function that have the same host scope.
Declarations that have different
host scopes have completely distinct sets of default arguments.
That
is, declarations in inner scopes do not acquire default
arguments from declarations in outer scopes, and vice versa.
In
a given function declaration, each parameter subsequent to a
parameter with a default argument shall have a default argument
supplied in this or a previous declaration,
unless the parameter was expanded from a parameter pack,
or shall be a function parameter pack.
\begin{note}
A default argument
cannot be redefined by a later declaration
(not even to the same value)\iref{basic.def.odr}.
\end{note}
\begin{example}
\begin{codeblock}
void g(int = 0, ...);           // OK, ellipsis is not a parameter so it can follow
                                // a parameter with a default argument
void f(int, int);
void f(int, int = 7);
void h() {
  f(3);                         // OK, calls \tcode{f(3, 7)}
  void f(int = 1, int);         // error: does not use default from surrounding scope
}
void m() {
  void f(int, int);             // has no defaults
  f(4);                         // error: wrong number of arguments
  void f(int, int = 5);         // OK
  f(4);                         // OK, calls \tcode{f(4, 5);}
  void f(int, int = 5);         // error: cannot redefine, even to same value
}
void n() {
  f(6);                         // OK, calls \tcode{f(6, 7)}
}
template<class ... T> struct C {
  void f(int n = 0, T...);
};
C<int> c;                       // OK, instantiates declaration \tcode{void C::f(int n = 0, int)}
\end{codeblock}
\end{example}
For a given inline function defined in different translation units,
the accumulated sets of default arguments at the end of the
translation units shall be the same; no diagnostic is required.
If a friend declaration $D$ specifies a default argument expression,
that declaration shall be a definition and there shall be no other
declaration of the function or function template
which is reachable from $D$ or from which $D$ is reachable.

\pnum
\indextext{argument!type checking of default}%
\indextext{argument!binding of default}%
\indextext{argument!evaluation of default}%
The default argument has the
same semantic constraints as the initializer in a
declaration of a variable of the parameter type, using the
copy-initialization semantics\iref{dcl.init}.
The names in the
default argument are looked up, and the semantic constraints are checked,
at the point where the default argument appears, except that
an immediate invocation\iref{expr.const.imm} that
is a potentially-evaluated subexpression\iref{intro.execution} of
the \grammarterm{initializer-clause} in a \grammarterm{parameter-declaration} is
neither evaluated
nor checked for whether it is a constant expression at that point.
Name lookup and checking of semantic constraints for default
arguments of templated functions are performed as described in~\ref{temp.inst}.
\begin{example}
In the following code,
\indextext{argument!example of default}%
\tcode{g}
will be called with the value
\tcode{f(2)}:

\begin{codeblock}
int a = 1;
int f(int);
int g(int x = f(a));            // default argument: \tcode{f(::a)}

void h() {
  a = 2;
  {
    int a = 3;
    g();                        // \tcode{g(f(::a))}
  }
}
\end{codeblock}
\end{example}
\begin{note}
A default argument is a complete-class context\iref{class.mem}.
Access checking applies to names in default arguments as
described in \ref{class.access}.
\end{note}

\pnum
Except for member functions of templated classes, the
default arguments in a member function definition that appears
outside of the class definition
are added to the set of default arguments provided by the
member function declaration in the class definition;
the program is ill-formed if a default constructor\iref{class.default.ctor},
copy or move constructor\iref{class.copy.ctor}, or
copy or move assignment operator\iref{class.copy.assign}
is so declared.
Default arguments for a member function of a templated class
shall be specified on the initial declaration of the member
function within the templated class.
\begin{example}
\begin{codeblock}
class C {
  void f(int i = 3);
  void g(int i, int j = 99);
};

void C::f(int i = 3) {}         // error: default argument already specified in class scope
void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no arguments
\end{codeblock}
\end{example}

\pnum
\begin{note}
A local variable cannot be odr-used\iref{term.odr.use}
in a default argument.
\end{note}
\begin{example}
\begin{codeblock}
void f() {
  int i;
  extern void g(int x = i);         // error
  extern void h(int x = sizeof(i)); // OK
  // ...
}
\end{codeblock}
\end{example}

\pnum
\begin{note}
The keyword
\keyword{this}
cannot appear in a default argument of a member function;
see~\ref{expr.prim.this}.
\begin{example}
\begin{codeblock}
class A {
  void f(A* p = this) { }           // error
};
\end{codeblock}
\end{example}
\end{note}

\pnum
\indextext{argument!evaluation of default}%
A default argument is evaluated each time the function is called
with no argument for the corresponding parameter.
\indextext{argument!scope of default}%
A parameter shall not appear as a potentially evaluated expression
in a default argument.
\indextext{argument and name hiding!default}%
\begin{note}
Parameters of a function declared before a default argument
are in scope and can hide namespace and class member names.
\end{note}
\begin{example}
\begin{codeblock}
int a;
int f(int a, int b = a);            // error: parameter \tcode{a} used as default argument
typedef int I;
int g(float I, int b = I(2));       // error: parameter \tcode{I} found
int h(int a, int b = sizeof(a));    // OK, unevaluated operand\iref{term.unevaluated.operand}
\end{codeblock}
\end{example}
A non-static member shall not be designated in a default argument unless
\begin{itemize}
\item
it is designated by
the \grammarterm{id-expression} or \grammarterm{splice-expression}
of a class member access expression\iref{expr.ref},
\item
it is designated by an expression
used to form a pointer to member\iref{expr.unary.op}, or
\item
it appears as the operand of
a \grammarterm{reflect-expression}\iref{expr.reflect}.
\end{itemize}
\begin{example}
The declaration of
\tcode{X::mem1()}
in the following example is ill-formed because no object is supplied for the
non-static member
\tcode{X::a}
used as an initializer.
\begin{codeblock}
int b;
class X {
  int a;
  int mem1(int i = a);                      // error: non-static member \tcode{a} used as default argument
  int mem2(int i = b);                      // OK, use \tcode{X::b}
  consteval void mem3(std::meta::info r = ^^a) {}   // OK
  int mem4(int i = [:^^a:]);                // error: non-static member \tcode{a} designated in default argument
  static int b;
};
\end{codeblock}
The declaration of
\tcode{X::mem2()}
is meaningful, however, since no object is needed to access the static member
\tcode{X::b}.
Classes, objects, and members are described in \ref{class}.
\end{example}
A default argument is not part of the
type of a function.
\begin{example}
\begin{codeblock}
int f(int = 0);

void h() {
  int j = f(1);
  int k = f();                      // OK, means \tcode{f(0)}
}

int (*p1)(int) = &f;
int (*p2)() = &f;                   // error: type mismatch
\end{codeblock}
\end{example}
\begin{note}
When an overload set contains a declaration of a function
whose host scope is $S$,
any default argument associated with any reachable declaration
whose host scope is $S$
is available to the call\iref{over.match.viable}.
\end{note}
\begin{note}
The candidate might have been found through a \grammarterm{using-declarator}
from which the declaration that provides the default argument is not reachable.
\end{note}

\pnum
\indextext{argument and virtual function!default}%
A virtual function call\iref{class.virtual} uses the default
arguments in the declaration of the virtual function determined
by the static type of the pointer or reference denoting the
object.
An overriding function in a derived class does not
acquire default arguments from the function it overrides.
\begin{example}
\begin{codeblock}
struct A {
  virtual void f(int a = 7);
};
struct B : public A {
  void f(int a);
};
void m() {
  B* pb = new B;
  A* pa = pb;
  pa->f();          // OK, calls \tcode{pa->B::f(7)}
  pb->f();          // error: wrong number of arguments for \tcode{B::f()}
}
\end{codeblock}
\end{example}
\indextext{declaration!default argument|)}%
\indextext{declarator!meaning of|)}

\rSec1[dcl.contract]{Function contract specifiers}
\rSec2[dcl.contract.func]{General}

\indextext{contract assertion!function|(}%

\begin{bnf}
\nontermdef{function-contract-specifier-seq}\br
    function-contract-specifier \opt{function-contract-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{function-contract-specifier}\br
  precondition-specifier\br
  postcondition-specifier
\end{bnf}

\begin{bnf}
\nontermdef{precondition-specifier}\br
  \terminal{pre} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{postcondition-specifier}\br
  \terminal{post} \opt{attribute-specifier-seq} \terminal{(} \opt{result-name-introducer} conditional-expression \terminal{)}
\end{bnf}

\pnum
\indexdefn{contract assertion!postcondition|see{assertion, postcondition}}
\indexdefn{contract assertion!precondition|see{assertion, precondition}}
A \defnadj{function}{contract assertion}
is a contract assertion\iref{basic.contract.general}
associated with a function.
A \grammarterm{precondition-specifier}
introduces a \defnadj{precondition}{assertion},
which is a function contract assertion
associated with entering a function.
A \grammarterm{postcondition-specifier}
introduces a \defnadj{postcondition}{assertion},
which is a function contract assertion
associated with exiting a function normally.
\begin{note}
A postcondition assertion
is not associated with exiting a function
in any other fashion,
such as via an exception\iref{expr.throw}
or via a call to \tcode{longjmp}\iref{csetjmp.syn}.
\end{note}

\pnum
The predicate\iref{basic.contract.general}
of a function contract assertion
is its \grammarterm{conditional-expression}
contextually converted to \tcode{bool}.

\pnum
Each \grammarterm{function-contract-specifier}
of a \grammarterm{function-contract-specifier-seq} (if any)
of an unspecified first declaration\iref{basic.def}
of a function
introduces a corresponding function contract assertion for that function.
The optional \grammarterm{attribute-specifier-seq}
following \tcode{pre} or \tcode{post}
appertains to the introduced contract assertion.
\begin{note}
The \grammarterm{function-contract-specifier-seq}
of a \grammarterm{lambda-declarator}
applies to the function call operator or operator template
of the corresponding closure type\iref{expr.prim.lambda.closure}.
\end{note}

\pnum
A declaration $D$
of a function or function template \placeholder{f}
that is not a first declaration shall have either
no \grammarterm{function-contract-specifier-seq}
or the same \grammarterm{function-contract-specifier-seq} (see below)
as any first declaration $F$ reachable from $D$.
If $D$ and $F$ are
in different translation units,
a diagnostic is required only if $D$ is attached to a named module.
If a declaration $F_1$ is a
first declaration of \tcode{f}
in one translation unit and
a declaration $F_2$ is a
first declaration of \tcode{f} in another translation unit,
$F_1$ and $F_2$ shall specify the same
\grammarterm{function-contract-specifier-seq}, no diagnostic required.

\pnum
A \grammarterm{function-contract-specifier-seq} $S_1$
is the same as
a \grammarterm{function-contract-specifier-seq} $S_2$
if $S_1$ and $S_2$ consist of
the same \grammarterm{function-contract-specifier}s
in the same order.
A \grammarterm{function-contract-specifier} $C_1$
on a function declaration $D_1$ is
the same as
a \grammarterm{function-contract-specifier} $C_2$
on a function declaration $D_2$
if
\begin{itemize}
\item
their predicates $P_1$ and $P_2$ would
satisfy the one-definition rule\iref{basic.def.odr}
if placed in function definitions on
the declarations $D_1$ and $D_2$, respectively, except for
\begin{itemize}
\item
renaming of the parameters of \placeholder{f},
\item
renaming of template parameters of
a template enclosing \placeholder{}, and
\item
renaming of the result binding\iref{dcl.contract.res}, if any,
\end{itemize}
and,
if $D_1$ and $D_2$ are in different translation units,
corresponding entities defined within each predicate
behave as if there is a single entity with a single definition, and
\item
both $C_1$ and $C_2$
specify a \grammarterm{result-name-introducer}
or neither do.
\end{itemize}
If this condition is not met
solely due to the comparison of two \grammarterm{lambda-expression}s
that are contained within $P_1$ and $P_2$,
no diagnostic is required.

\begin{note}
Equivalent
\grammarterm{function-contract-specifier-seq}s
apply to all uses and definitions
of a function  across all translation units.
\end{note}
\begin{example}
\begin{codeblock}

bool b1, b2;

void f() pre (b1) pre ([]{ return b2; }());
void f();                       // OK, \grammarterm{function-contract-specifier}s omitted
void f() pre (b1) pre ([]{ return b2; }()); // error: closures have different types.
void f() pre (b1);              // error: \grammarterm{function-contract-specifier}s only partially repeated

int g() post(r : b1);
int g() post(b1);       // error: mismatched \grammarterm{result-name-introducer} presence

namespace N {
  void h() pre (b1);
  bool b1;
  void h() pre (b1);    // error: \grammarterm{function-contract-specifier}s differ according to
                        // the one-definition rule\iref{basic.def.odr}.
}
\end{codeblock}
\end{example}

\pnum
A virtual function\iref{class.virtual},
a deleted function\iref{dcl.fct.def.delete},
or a function defaulted on its first declaration\iref{dcl.fct.def.default}
shall not have a \grammarterm{function-contract-specifier-seq}.

\pnum
If the predicate of a postcondition assertion
of a function \placeholder{f}
odr-uses\iref{basic.def.odr}
a non-reference parameter of \placeholder{f},
that parameter
and the corresponding parameter on all declarations of \placeholder{f}
shall have \keyword{const} type.
\begin{note}
This requirement applies
even to declarations that do not specify the \grammarterm{postcondition-specifier}.
Parameters with array or function type
will decay to non-\keyword{const} types
even if a \keyword{const} qualifier is present.
\begin{example}
\begin{codeblock}
int f(const int i[10])
  post(r : r == i[0]);  // error: \tcode{i} has type \tcode{const int *} (not \tcode{int* const}).
\end{codeblock}
\end{example}
\end{note}

\pnum
\begin{note}
The function contract assertions of a function
are evaluated even when invoked indirectly,
such as through a pointer to function or a pointer to member function.
A pointer to function,
pointer to member function,
or function type alias
cannot have a \grammarterm{function-contract-specifier-seq}
associated directly with it.
\end{note}

\pnum
The function contract assertions of a function
are considered to be \defnx{needed}{needed!function contract assertion}\iref{temp.inst} when
\begin{itemize}
\item
the function is odr-used\iref{basic.def.odr} or
\item
the function is defined.
\end{itemize}
\begin{note}
Overload resolution does not consider
\grammarterm{function-contract-specifier}s\iref{temp.deduct,temp.inst}.
\begin{example}
\begin{codeblock}
template <typename T>  void f(T t) pre( t == "" );
template <typename T>  void f(T&& t);
void g()
{
  f(5);     // error: ambiguous
}
\end{codeblock}
\end{example}
\end{note}


\rSec2[dcl.contract.res]{Referring to the result object}

\begin{bnf}
\nontermdef{attributed-identifier}\br
  identifier \opt{attribute-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{result-name-introducer}\br
  attributed-identifier \terminal{:}
\end{bnf}

\pnum
The \grammarterm{result-name-introducer}
of a \grammarterm{postcondition-specifier}
is a declaration.
The \grammarterm{result-name-introducer}
introduces the \grammarterm{identifier}
as the name of a \defn{result binding}
of the associated function.
If a postcondition assertion has a \grammarterm{result-name-introducer}
and the return type of the function is \cv{} \keyword{void},
the program is ill-formed.
A result binding denotes
the object or reference returned by
invocation of that function.
The type of a result binding
is the return type of its associated function.
The optional \grammarterm{attribute-specifier-seq}
of the \grammarterm{attributed-identifier}
in the \grammarterm{result-name-introducer}
appertains to the result binding so introduced.
\begin{note}
An \grammarterm{id-expression}
that names a result binding is a \keyword{const} lvalue\iref{expr.prim.id.unqual}.
\end{note}

\begin{example}
\begin{codeblock}
int f()
  post(r : r == 1)
{
  return 1;
}
int i = f();    // Postcondition check succeeds.
\end{codeblock}
\end{example}

\begin{example}
\begin{codeblock}
struct A {};
struct B {
  B() {}
  B(const B&) {}
};

template <typename T>
T f(T* const ptr)
  post(r: &r == ptr)
{
  return {};
}

int main() {
  A a = f(&a);  // The postcondition check can fail if the implementation introduces
                // a temporary for the return value\iref{class.temporary}.
  B b = f(&b);  // The postcondition check succeeds, no temporary is introduced.
}
\end{codeblock}
\end{example}


\pnum
When the declared return type
of a non-templated function
contains a placeholder type,
a \grammarterm{postcondition-specifier}
with a \grammarterm{result-name-introducer}
shall be present only on a definition.
\begin{example}
\begin{codeblock}
auto g(auto&)
  post (r: r >= 0);     // OK, \tcode{g} is a template.

auto h()
  post (r: r >= 0);     // error: cannot name the return value

auto k()
  post (r: r >= 0)      // OK
{
  return 0;
}
\end{codeblock}
\end{example}

\indextext{contract assertion!function|)}%

\rSec1[dcl.init]{Initializers}%

\rSec2[dcl.init.general]{General}%
\indextext{initialization|(}

\pnum
The process of initialization described in \ref{dcl.init} applies to
all initializations regardless of syntactic context, including the
initialization of a function parameter\iref{expr.call}, the
initialization of a return value\iref{stmt.return}, or when an
initializer follows a declarator.

\begin{bnf}
\nontermdef{initializer}\br
    brace-or-equal-initializer\br
    \terminal{(} expression-list \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{brace-or-equal-initializer}\br
    \terminal{=} initializer-clause\br
    braced-init-list
\end{bnf}

\begin{bnf}
\nontermdef{initializer-clause}\br
    assignment-expression\br
    braced-init-list
\end{bnf}

\begin{bnf}
\nontermdef{braced-init-list}\br
    \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br
    \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br
    \terminal{\{} \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{initializer-list}\br
    initializer-clause \opt{\terminal{...}}\br
    initializer-list \terminal{,} initializer-clause \opt{\terminal{...}}
\end{bnf}

\begin{bnf}
\nontermdef{designated-initializer-list}\br
    designated-initializer-clause\br
    designated-initializer-list \terminal{,} designated-initializer-clause
\end{bnf}

\begin{bnf}
\nontermdef{designated-initializer-clause}\br
    designator brace-or-equal-initializer
\end{bnf}

\begin{bnf}
\nontermdef{designator}\br
    \terminal{.} identifier
\end{bnf}

\begin{bnf}
\nontermdef{expr-or-braced-init-list}\br
    expression\br
    braced-init-list
\end{bnf}

\begin{note}
The rules in \ref{dcl.init} apply even if the grammar permits only
the \grammarterm{brace-or-equal-initializer} form
of \grammarterm{initializer} in a given context.
\end{note}

\pnum
Except for objects declared with the \keyword{constexpr} specifier, for which see~\ref{dcl.constexpr},
an \grammarterm{initializer} in the definition of a variable can consist of
arbitrary expressions involving literals and previously declared
variables and functions,
regardless of the variable's storage duration.
\begin{example}
\begin{codeblock}
int f(int);
int a = 2;
int b = f(a);
int c(b);
\end{codeblock}
\end{example}

\pnum
\begin{note}
Default arguments are more restricted; see~\ref{dcl.fct.default}.
\end{note}

\pnum
\begin{note}
The order of initialization of variables with static storage duration is described in~\ref{basic.start}
and~\ref{stmt.dcl}.
\end{note}

\pnum
A declaration $D$ of a variable with linkage
shall not have an \grammarterm{initializer}
if $D$ inhabits a block scope.

\pnum
\indextext{initialization!default}%
\indextext{variable!indeterminate uninitialized}%
\indextext{initialization!zero-initialization}%
To \defnx{zero-initialize}{zero-initialization}
an object or reference of type \tcode{T} means:
\begin{itemize}
\item
if \tcode{T} is \tcode{std::meta::info},
the object is initialized to a null reflection value;
\item
if \tcode{T} is any other scalar type\iref{term.scalar.type},
the object is initialized to the value
obtained by converting the integer literal \tcode{0} (zero) to \tcode{T};
\begin{footnote}
As specified in~\ref{conv.ptr}, converting an integer
literal whose value is
\tcode{0}
to a pointer type results in a null pointer value.
\end{footnote}

\item
if
\tcode{T}
is a (possibly cv-qualified) non-union class type,
its padding bits\iref{term.padding.bits} are initialized to zero bits and
each non-static data member,
each non-virtual base class subobject, and,
if the object is not a base class subobject,
each virtual base class subobject
is zero-initialized;

\item
if
\tcode{T}
is a (possibly cv-qualified) union type,
its padding bits\iref{term.padding.bits} are initialized to zero bits and
the
object's first non-static named
data member
is zero-initialized;

\item
if
\tcode{T}
is an array type,
each element is zero-initialized;
\item
if
\tcode{T}
is a reference type, no initialization is performed.
\end{itemize}

\pnum
To
\defnx{default-initialize}{default-initialization}
an object of type
\tcode{T}
means:

\begin{itemize}
\item
If
\tcode{T}
is a (possibly cv-qualified) class type\iref{class},
constructors are considered. The applicable constructors are
enumerated\iref{over.match.ctor}, and the best one for the
\grammarterm{initializer} \tcode{()} is chosen through
overload resolution\iref{over.match}. The constructor thus selected
is called, with an empty argument list, to initialize the object.

\item
If
\tcode{T}
is an array type,
the semantic constraints of default-initializing a hypothetical element
shall be met and
each element is default-initialized.

\item
If \tcode{T} is \tcode{std::meta::info}, the object is zero-initialized.

\item
Otherwise,
no initialization is performed.
\end{itemize}

\pnum
A type \cv{}~\tcode{T} is \defn{const-default-constructible} if
\begin{itemize}
\item
\tcode{T} is \tcode{std::meta::info};
\item
\tcode{T} is \tcode{std::nullptr_t};
\item
default-initialization of \tcode{T} would invoke
a user-provided constructor of \tcode{T} (not inherited from a base class);
\item
\tcode{T} is a class type where
\begin{itemize}
\item
each direct non-variant non-static data member of \tcode{T}
has a default member initializer or
is of const-default-constructible type,
\item
if \tcode{T} is a union with at least one non-static data member,
exactly one variant member has a default member initializer,
\item
if \tcode{T} is not a union,
the type of each anonymous union member is const-default-constructible, and
\item
each potentially constructed base class of \tcode{T} is const-default-constructible; or
\end{itemize}
\item
\tcode{T} is an array of const-default-constructible type.
\end{itemize}

If a program calls for the default-initialization of an object of a
const-qualified type \tcode{T},
\tcode{T} shall be a const-default-constructible type.

\pnum
To
\defnx{value-initialize}{value-initialization}
an object of type
\tcode{T}
means:

\begin{itemize}
\item
If
\tcode{T}
is a (possibly cv-qualified) class type\iref{class}, then
let \tcode{C} be the constructor selected to
default-initialize the object, if any.
If \tcode{C} is not user-provided, the object is first zero-initialized.
In all cases, the object is then default-initialized.

\item
If
\tcode{T}
is an array type,
the semantic constraints of value-initializing a hypothetical element
shall be met and
each element is value-initialized.

\item
Otherwise, the object is zero-initialized.
\end{itemize}

\pnum
A program that calls for default-initialization
or value-initialization
of an entity
of reference type is ill-formed.

\pnum
\begin{note}
For every object with static storage duration,
static initialization\iref{basic.start.static} is performed
at program startup before any other initialization takes place.
In some cases, additional initialization is done later.
\end{note}

\pnum
If no initializer is specified for an object, the object is default-initialized.

\pnum
If the entity being initialized does not have class or array type, the
\grammarterm{expression-list} in a
parenthesized initializer shall be a single expression.

\pnum
\indextext{initialization!copy}%
\indextext{initialization!direct}%
The initialization that occurs in the \tcode{=} form of a
\grammarterm{brace-or-equal-initializer} or
\grammarterm{condition}\iref{stmt.select},
as well as in argument passing, function return,
throwing an exception\iref{except.throw},
handling an exception\iref{except.handle},
and aggregate member initialization other than by a
\grammarterm{designated-initializer-clause}\iref{dcl.init.aggr},
is called
\defn{copy-initialization}.
\begin{note}
Copy-initialization can invoke a move\iref{class.copy.ctor}.
\end{note}

\pnum
The initialization that occurs
\begin{itemize}
\item for an \grammarterm{initializer} that is a
parenthesized \grammarterm{expression-list} or a \grammarterm{braced-init-list},
\item for a \grammarterm{new-initializer}\iref{expr.new},
\item in a \keyword{static_cast} expression\iref{expr.static.cast},
\item in a functional notation type conversion\iref{expr.type.conv}, and
\item in the \grammarterm{braced-init-list} form of a \grammarterm{condition}
\end{itemize}
is called
\defn{direct-initialization}.

\pnum
The semantics of initializers are as follows.
The
\indextext{type!destination}%
\term{destination type}
is the cv-unqualified type of the object or reference being initialized and the
\term{source type}
is the type of the initializer expression.
If the initializer is not a single (possibly parenthesized) expression, the
source type is not defined.
\begin{itemize}
\item
If the initializer is a (non-parenthesized) \grammarterm{braced-init-list}
or is \tcode{=} \grammarterm{braced-init-list}, the object or reference
is list-initialized\iref{dcl.init.list}.
\item
If the destination type is a reference type, see~\ref{dcl.init.ref}.
\item
If the destination type is an array of characters,
an array of \keyword{char8_t},
an array of \keyword{char16_t},
an array of \keyword{char32_t},
or an array of
\keyword{wchar_t},
and the initializer is a \grammarterm{string-literal}, see~\ref{dcl.init.string}.
\item If the initializer is \tcode{()}, the object is value-initialized.
\indextext{ambiguity!function declaration}%
\begin{note}
Since
\tcode{()}
is not permitted by the syntax for
\grammarterm{initializer},
\begin{codeblock}
X a();
\end{codeblock}
is not the declaration of an object of class
\tcode{X},
but the declaration of a function taking no arguments and returning an
\tcode{X}.
The form
\tcode{()}
can appear in certain other initialization contexts\iref{expr.new,
expr.type.conv,class.base.init}.
\end{note}

\item
Otherwise, if the destination type is an array,
the object is initialized as follows.
The \grammarterm{initializer} shall be of the form
\tcode{(} \grammarterm{expression-list} \tcode{)}.
Let $x_1$, $\dotsc$, $x_k$ be
the elements of the \grammarterm{expression-list}.
If the destination type is an array of unknown bound,
it is defined as having $k$ elements.
Let $n$ denote the array size after this potential adjustment.
If $k$ is greater than $n$,
the program is ill-formed.
Otherwise, the $i^\text{th}$ array element is copy-initialized with
$x_i$ for each $1 \leq i \leq k$, and
value-initialized for each $k < i \leq n$.
For each $1 \leq i < j \leq n$,
every value computation and side effect associated with
the initialization of the $i^\text{th}$ element of the array
is sequenced before those associated with
the initialization of the $j^\text{th}$ element.
\item
Otherwise, if the destination type is a class type:

\begin{itemize}
\item
If the initializer expression is a prvalue
and the cv-unqualified version of the source type
is the same as the destination type,
the initializer expression is used to initialize the destination object.
\begin{example}
\tcode{T x = T(T(T()));} value-initializes \tcode{x}\iref{basic.lval,expr.type.conv}.
\end{example}
\item
Otherwise, if the initialization is direct-initialization,
or if it is copy-initialization where the cv-unqualified version of the source
type is the same as or is derived from the class of the destination type,
constructors are considered.
The applicable constructors
are enumerated\iref{over.match.ctor}, and the best one is chosen
through overload resolution\iref{over.match}. Then:
\begin{itemize}
\item
If overload resolution is successful,
the selected constructor
is called to initialize the object, with the initializer
expression or \grammarterm{expression-list} as its argument(s).
\item
Otherwise, if no constructor is viable,
the destination type is
an aggregate class, and
the initializer is a parenthesized \grammarterm{expression-list},
the object is initialized as follows.
Let $e_1$, $\dotsc$, $e_n$ be the elements of the aggregate\iref{dcl.init.aggr}.
Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}.
If $k$ is greater than $n$, the program is ill-formed.
The element $e_i$ is copy-initialized with
$x_i$ for $1 \leq i \leq k$.
The remaining elements are initialized with
their default member initializers, if any, and
otherwise are value-initialized.
For each $1 \leq i < j \leq n$,
every value computation and side effect
associated with the initialization of $e_i$
is sequenced before those associated with the initialization of $e_j$.
\begin{note}
By contrast with direct-list-initialization,
narrowing conversions\iref{dcl.init.list} can appear,
designators are not permitted,
a temporary object bound to a reference
does not have its lifetime extended\iref{class.temporary}, and
there is no brace elision.
\begin{example}
\begin{codeblock}
struct A {
  int a;
  int&& r;
};

int f();
int n = 10;

A a1{1, f()};                   // OK, lifetime is extended
A a2(1, f());                   // well-formed, but dangling reference
A a3{1.0, 1};                   // error: narrowing conversion
A a4(1.0, 1);                   // well-formed, but dangling reference
A a5(1.0, std::move(n));        // OK
\end{codeblock}
\end{example}
\end{note}
\item
Otherwise, the initialization is ill-formed.
\end{itemize}

\item
Otherwise (i.e., for the remaining copy-initialization cases),
user-defined conversions that can convert from the
source type to the destination type or (when a conversion function
is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy},
and the best one is chosen through overload resolution\iref{over.match}.
If the conversion cannot be done or
is ambiguous, the initialization is ill-formed.  The function
selected is called with the initializer expression as its
argument; if the function is a constructor, the call is a prvalue
of the cv-unqualified version of the
destination type whose result object is initialized by the constructor.
The call is used
to direct-initialize, according to the rules above, the object
that is the destination of the copy-initialization.
\end{itemize}

\item
Otherwise, if the source type
is a (possibly cv-qualified) class type, conversion functions are
considered.
The applicable conversion functions are enumerated\iref{over.match.conv},
and the best one is chosen through overload
resolution\iref{over.match}.
The user-defined conversion so selected
is called to convert the initializer expression into the
object being initialized.
If the conversion cannot be done or is
ambiguous, the initialization is ill-formed.
\item
Otherwise, if the initialization is direct-initialization,
the source type is \tcode{std::nullptr_t}, and
the destination type is \tcode{bool},
the initial value of the object being initialized is \tcode{false}.
\item
Otherwise, the initial value of the object being initialized is
the (possibly converted) value of the initializer expression.
A standard conversion sequence\iref{conv} is used
to convert the initializer expression to
a prvalue of
the destination type;
no user-defined conversions are considered.
If the conversion cannot
be done, the initialization is ill-formed.
When initializing a bit-field with a value that it cannot represent, the
resulting value of the bit-field is
\impldefplain{value of bit-field that cannot represent!initializer}.
\indextext{initialization!\idxcode{const}}%
\begin{note}
An expression of type
``\cvqual{cv1} \tcode{T}''
can initialize an object of type
``\cvqual{cv2} \tcode{T}''
independently of
the cv-qualifiers
\cvqual{cv1}
and \cvqual{cv2}.

\begin{codeblock}
int a;
const int b = a;
int c = b;
\end{codeblock}
\end{note}
\end{itemize}

\pnum
An immediate invocation\iref{expr.const.imm} that is not evaluated where
it appears\iref{dcl.fct.default,class.mem.general}
is evaluated and checked for whether it is
a constant expression at the point where
the enclosing \grammarterm{initializer} is used in
a function call, a constructor definition, or an aggregate initialization.

\pnum
An \grammarterm{initializer-clause} followed by an ellipsis is a
pack expansion\iref{temp.variadic}.

\pnum
Initialization includes
the evaluation of all subexpressions of
each \grammarterm{initializer-clause} of
the initializer (possibly nested within \grammarterm{braced-init-list}{s}) and
the creation of any temporary objects for
function arguments or return values\iref{class.temporary}.

\pnum
If the destination type is not an aggregate
and the initializer is a parenthesized \grammarterm{expression-list},
the expressions are evaluated in the order
specified for function calls\iref{expr.call}.

\pnum
The same \grammarterm{identifier}
shall not appear in multiple \grammarterm{designator}{s} of a
\grammarterm{designated-initializer-list}.

\pnum
The \defnadj{deemed}{construction} of an object occurs when
its initialization completes;
for the purposes of~\ref{basic.start.term},
if the initialization is a full-expression,
deemed construction occurs when
the evaluation of that full-expression completes.
The object is deemed to be constructed,
even if the object is of non-class type or
no constructor of the object's class
is invoked for the initialization.
\begin{note}
Such an object might have been value-initialized
or initialized by aggregate initialization\iref{dcl.init.aggr}
or by an inherited constructor\iref{class.inhctor.init}.
\end{note}
Destroying an object of class type invokes the destructor of the class.
Destroying a scalar type has no effect other than
ending the lifetime of the object\iref{basic.life}.
Destroying an array destroys each element in reverse subscript order.

\pnum
A declaration that specifies the initialization of a variable,
whether from an explicit initializer or by default-initialization,
is called the \defn{initializing declaration} of that variable.
\begin{note}
In most cases
this is the defining declaration\iref{basic.def} of the variable,
but the initializing declaration
of a non-inline static data member\iref{class.static.data}
can be the declaration within the class definition
and not the definition (if any) outside it.
\end{note}

\rSec2[dcl.init.aggr]{Aggregates}%
\indextext{aggregate}%
\indextext{initialization!aggregate}%
\indextext{aggregate initialization}%
\indextext{initialization!array}%
\indextext{initialization!class object}%
\indextext{class object initialization|see{constructor}}%
\indextext{\idxcode{\{\}}!initializer list}

\pnum
An \defn{aggregate} is an array or a class\iref{class} with
\begin{itemize}
\item
no user-declared or inherited constructors\iref{class.ctor},
\item
no private or protected direct non-static data members\iref{class.access},
\item
no private or protected direct base classes\iref{class.access.base}, and
\item
no virtual functions\iref{class.virtual} or virtual base classes\iref{class.mi}.
\end{itemize}
\begin{note}
Aggregate initialization does not allow accessing
protected and private base class' members, including constructors.
\end{note}

\pnum
The \defnx{elements}{aggregate!elements} of an aggregate are:
\begin{itemize}
\item
for an array, the array elements in increasing subscript order, or
\item
for a class, the direct base classes in declaration order,
followed by the direct non-static data members\iref{class.mem}
that are not members of an anonymous union, in declaration order.
\end{itemize}

\pnum
When an aggregate is initialized by an initializer list
as specified in~\ref{dcl.init.list},
the elements of the initializer list are taken as initializers
for the elements of the aggregate.
The \defnx{explicitly initialized elements}{explicitly initialized elements!aggregate}
of the aggregate are determined as follows:
\begin{itemize}
\item
If the initializer list is
a brace-enclosed \grammarterm{designated-initializer-list},
the aggregate shall be of class type,
the \grammarterm{identifier} in each \grammarterm{designator}
shall name a direct non-static data member of the class, and
the explicitly initialized elements of the aggregate
are the elements that are, or contain, those members.
\item
If the initializer list is a brace-enclosed \grammarterm{initializer-list},
the explicitly initialized elements of the aggregate
are those for which an element of the initializer list
appertains to the aggregate element or to a subobject thereof (see below).
\item
Otherwise, the initializer list must be \tcode{\{\}},
and there are no explicitly initialized elements.
\end{itemize}

\pnum
For each explicitly initialized element:
\begin{itemize}
\item
If the element is an anonymous union member and
the initializer list is
a brace-enclosed \grammarterm{designated-initializer-list},
the element is initialized by the
\grammarterm{braced-init-list} \tcode{\{ }\placeholder{D}\tcode{ \}},
where \placeholder{D} is the \grammarterm{designated-initializer-clause}
naming a member of the anonymous union member.
There shall be only one such \grammarterm{designated-initializer-clause}.
\begin{example}
\begin{codeblock}
struct C {
  union {
    int a;
    const char* p;
  };
  int x;
} c = { .a = 1, .x = 3 };
\end{codeblock}
initializes \tcode{c.a} with 1 and \tcode{c.x} with 3.
\end{example}
\item
Otherwise, if the initializer list is
a brace-enclosed \grammarterm{designated-initializer-list},
the element is initialized with the \grammarterm{brace-or-equal-initializer}
of the corresponding \grammarterm{designated-initializer-clause}.
If that initializer is of the form
\tcode{= }\grammarterm{assignment-expression}
and
a narrowing conversion\iref{dcl.init.list} is required
to convert the expression, the program is ill-formed.
\begin{note}
The form of the initializer determines
whether copy-initialization or direct-initialization is performed.
\end{note}
\item
Otherwise,
the initializer list is a brace-enclosed \grammarterm{initializer-list}.
If an \grammarterm{initializer-clause} appertains to the aggregate element,
then the aggregate element is copy-initialized from the \grammarterm{initializer-clause}.
Otherwise,
the aggregate element is copy-initialized
from a brace-enclosed \grammarterm{initializer-list}
consisting of all of the \grammarterm{initializer-clause}s
that appertain to subobjects of the aggregate element,
in the order of appearance.
\begin{note}
If an initializer is itself an initializer list,
the element is list-initialized, which will result in a recursive application
of the rules in this subclause if the element is an aggregate.
\end{note}
\begin{example}
\begin{codeblock}
struct A {
  int x;
  struct B {
    int i;
    int j;
  } b;
} a = { 1, { 2, 3 } };
\end{codeblock}
initializes
\tcode{a.x}
with 1,
\tcode{a.b.i}
with 2,
\tcode{a.b.j}
with 3.

\begin{codeblock}
struct base1 { int b1, b2 = 42; };
struct base2 {
  base2() {
    b3 = 42;
  }
  int b3;
};
struct derived : base1, base2 {
  int d;
};

derived d1{{1, 2}, {}, 4};
derived d2{{}, {}, 4};
\end{codeblock}
initializes
\tcode{d1.b1} with 1,
\tcode{d1.b2} with 2,
\tcode{d1.b3} with 42,
\tcode{d1.d} with 4, and
\tcode{d2.b1} with 0,
\tcode{d2.b2} with 42,
\tcode{d2.b3} with 42,
\tcode{d2.d} with 4.
\end{example}
\end{itemize}

\pnum
For a non-union aggregate,
each element that is not an explicitly initialized element
is initialized as follows:
\begin{itemize}
\item
If the element has a default member initializer\iref{class.mem},
the element is initialized from that initializer.
\item
Otherwise, if the element is not a reference, the element
is copy-initialized from an empty initializer list\iref{dcl.init.list}.
\item
Otherwise, the program is ill-formed.
\end{itemize}
If the aggregate is a union and the initializer list is empty, then
\begin{itemize}
\item
if any variant member has a default member initializer,
that member is initialized from its default member initializer;
\item
otherwise, the first member of the union (if any)
is copy-initialized from an empty initializer list.
\end{itemize}

\pnum
\begin{example}
\begin{codeblock}
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
\end{codeblock}
initializes
\tcode{ss.a}
with 1,
\tcode{ss.b}
with \tcode{"asdf"},
\tcode{ss.c}
with the value of an expression of the form
\tcode{int\{\}}
(that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]}
(that is, \tcode{'s'}).

\begin{codeblock}
struct A {
  string a;
  int b = 42;
  int c = -1;
};
\end{codeblock}

\tcode{A\{.c=21\}} has the following steps:
\begin{itemize}
\item Initialize \tcode{a} with \tcode{\{\}}
\item Initialize \tcode{b} with \tcode{= 42}
\item Initialize \tcode{c} with \tcode{= 21}
\end{itemize}
\end{example}

\pnum
The initializations of the elements of the aggregate
are evaluated in the element order.
That is,
all value computations and side effects associated with a given element
are sequenced before
those of any element that follows it in order.

\pnum
An aggregate that is a class can also be initialized with a single
expression not enclosed in braces, as described in~\ref{dcl.init}.

\pnum
The destructor for each element of class type
other than an anonymous union member
is potentially invoked\iref{class.dtor}
from the context where the aggregate initialization occurs.
\begin{note}
This provision ensures that destructors can be called
for fully-constructed subobjects
in case an exception is thrown\iref{except.ctor}.
\end{note}

\pnum
The number of elements\iref{dcl.array} in an array of unknown bound
initialized with a brace-enclosed \grammarterm{initializer-list}
is the number of explicitly initialized elements of the array.
\begin{example}
\begin{codeblock}
int x[] = { 1, 3, 5 };
\end{codeblock}
declares and initializes
\tcode{x}
as a one-dimensional array that has three elements
since no size was specified and there are three initializers.
\end{example}
\begin{example}
In
\begin{codeblock}
struct X { int i, j, k; };
X a[] = { 1, 2, 3, 4, 5, 6 };
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
\end{codeblock}
\tcode{a} and \tcode{b} have the same value.
\end{example}
An array of unknown bound shall not be initialized with
an empty \grammarterm{braced-init-list} \tcode{\{\}}.
\begin{footnote}
The syntax provides for empty \grammarterm{braced-init-list}{s},
but nonetheless \Cpp{} does not have zero length arrays.
\end{footnote}
\begin{note}
A default member initializer does not determine the bound for a member
array of unknown bound.  Since the default member initializer is
ignored if a suitable \grammarterm{mem-initializer} is present\iref{class.base.init},
the default member initializer is not
considered to initialize the array of unknown bound.
\begin{example}
\begin{codeblock}
struct S {
  int y[] = { 0 };          // error: non-static data member of incomplete type
};
\end{codeblock}
\end{example}
\end{note}

\pnum
\begin{note}
Static data members,
non-static data members of anonymous union members,
and
unnamed bit-fields
are not considered elements of the aggregate.
\begin{example}
\begin{codeblock}
struct A {
  int i;
  static int s;
  int j;
  int :17;
  int k;
} a = { 1, 2, 3 };
\end{codeblock}

Here, the second initializer 2 initializes
\tcode{a.j}
and not the static data member
\tcode{A::s}, and the third initializer 3 initializes \tcode{a.k}
and not the unnamed bit-field before it.
\end{example}
\end{note}

\pnum
If a member has a default member initializer
and a potentially-evaluated subexpression thereof is an aggregate
initialization that would use that default member initializer,
the program is ill-formed.
\begin{example}
\begin{codeblock}
struct A;
extern A a;
struct A {
  const A& a1 { A{a,a} };       // OK
  const A& a2 { A{} };          // error
};
A a{a,a};                       // OK

struct B {
  int n = B{}.n;                // error
};
\end{codeblock}
\end{example}

\pnum
When initializing a multidimensional array,
the
\grammarterm{initializer-clause}{s}
initialize the elements with the last (rightmost) index of the array
varying the fastest\iref{dcl.array}.
\begin{example}
\begin{codeblock}
int x[2][2] = { 3, 1, 4, 2 };
\end{codeblock}
initializes
\tcode{x[0][0]}
to
\tcode{3},
\tcode{x[0][1]}
to
\tcode{1},
\tcode{x[1][0]}
to
\tcode{4},
and
\tcode{x[1][1]}
to
\tcode{2}.
On the other hand,
\begin{codeblock}
float y[4][3] = {
  { 1 }, { 2 }, { 3 }, { 4 }
};
\end{codeblock}
initializes the first column of
\tcode{y}
(regarded as a two-dimensional array)
and leaves the rest zero.
\end{example}

\pnum
Each \grammarterm{initializer-clause} in
a brace-enclosed \grammarterm{initializer-list}
is said to \defn{appertain}
to an element of the aggregate being initialized or
to an element of one of its subaggregates.
Considering the sequence of \grammarterm{initializer-clause}s,
and the sequence of aggregate elements
initially formed as the sequence of elements of the aggregate being initialized
and potentially modified as described below,
each \grammarterm{initializer-clause} appertains to
the corresponding aggregate element if
\begin{itemize}
\item
the aggregate element is not an aggregate, or
\item
the \grammarterm{initializer-clause} begins with a left brace, or
\item
the \grammarterm{initializer-clause} is an expression and
an implicit conversion sequence can be formed
that converts the expression to the type of the aggregate element, or
\item
the aggregate element is an aggregate that itself has no aggregate elements.
\end{itemize}
Otherwise,
the aggregate element is an aggregate and
that subaggregate is replaced in the list of aggregate elements by
the sequence of its own aggregate elements, and
the appertainment analysis resumes with
the first such element and the same \grammarterm{initializer-clause}.
\begin{note}
These rules apply recursively to the aggregate's subaggregates.
\begin{example}
In
\begin{codeblock}
struct S1 { int a, b; };
struct S2 { S1 s, t; };

S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
S2 y[2] = {
  {
    { 1, 2 },
    { 3, 4 }
  },
  {
    { 5, 6 },
    { 7, 8 }
  }
};
\end{codeblock}
\tcode{x} and \tcode{y} have the same value.
\end{example}
\end{note}
This process continues
until all \grammarterm{initializer-clause}s have been exhausted.
If any \grammarterm{initializer-clause} remains
that does not appertain to
an element of the aggregate or one of its subaggregates,
the program is ill-formed.
\begin{example}
\begin{codeblock}
char cv[4] = { 'a', 's', 'd', 'f', 0 };     // error: too many initializers
\end{codeblock}
\end{example}

\pnum
\begin{example}
\begin{codeblock}
float y[4][3] = {
  { 1, 3, 5 },
  { 2, 4, 6 },
  { 3, 5, 7 },
};
\end{codeblock}
is a completely-braced initialization:
1, 3, and 5 initialize the first row of the array
\tcode{y[0]},
namely
\tcode{y[0][0]},
\tcode{y[0][1]},
and
\tcode{y[0][2]}.
Likewise the next two lines initialize
\tcode{y[1]}
and
\tcode{y[2]}.
The initializer ends early and therefore
\tcode{y[3]}'s
elements are initialized as if explicitly initialized with an
expression of the form
\tcode{float()},
that is, are initialized with
\tcode{0.0}.
In the following example, braces in the
\grammarterm{initializer-list}
are elided;
however the
\grammarterm{initializer-list}
has the same effect as the completely-braced
\grammarterm{initializer-list}
of the above example,
\begin{codeblock}
float y[4][3] = {
  1, 3, 5, 2, 4, 6, 3, 5, 7
};
\end{codeblock}

The initializer for
\tcode{y}
begins with a left brace, but the one for
\tcode{y[0]}
does not,
therefore three elements from the list are used.
Likewise the next three are taken successively for
\tcode{y[1]}
and
\tcode{y[2]}.
\end{example}

\pnum
\begin{note}
The initializer for an empty subaggregate is needed
if any initializers are provided for subsequent elements.
\begin{example}
\begin{codeblock}
struct S { } s;
struct A {
  S s1;
  int i1;
  S s2;
  int i2;
  S s3;
  int i3;
} a = {
  { },              // Required initialization
  0,
  s,                // Required initialization
  0
};                  // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized
\end{codeblock}
\end{example}
\end{note}

\pnum
\begin{example}
\begin{codeblock}
struct A {
  int i;
  operator int();
};
struct B {
  A a1, a2;
  int z;
};
A a;
B b = { 4, a, a };
\end{codeblock}
Braces are elided around the
\grammarterm{initializer-clause}
for
\tcode{b.a1.i}.
\tcode{b.a1.i}
is initialized with 4,
\tcode{b.a2}
is initialized with
\tcode{a},
\tcode{b.z}
is initialized with whatever
\tcode{a.operator int()}
returns.
\end{example}

\pnum
\indextext{initialization!array of class objects}%
\begin{note}
An aggregate array or an aggregate class can contain elements of a
class type with a user-declared constructor\iref{class.ctor}.
Initialization of these aggregate objects is described in~\ref{class.expl.init}.
\end{note}

\pnum
\begin{note}
Whether the initialization of aggregates with static storage duration
is static or dynamic is specified
in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and~\ref{stmt.dcl}.
\end{note}

\pnum
\indextext{initialization!\idxcode{union}}%
When a union is initialized with an initializer list,
there shall not be more than one
explicitly initialized element.
\begin{example}
\begin{codeblock}
union u { int a; const char* b; };
u a = { 1 };
u b = a;
u c = 1;                        // error
u d = { 0, "asdf" };            // error
u e = { "asdf" };               // error
u f = { .b = "asdf" };
u g = { .a = 1, .b = "asdf" };  // error
\end{codeblock}
\end{example}

\pnum
\begin{note}
As described above,
the braces around the
\grammarterm{initializer-clause}
for a union member can be omitted if the
union is a member of another aggregate.
\end{note}

\rSec2[dcl.init.string]{Character arrays}%
\indextext{initialization!character array}

\pnum
\indextext{UTF-8}%
\indextext{UTF-16}%
\indextext{UTF-32}%
An array of ordinary character type\iref{basic.fundamental},
\keyword{char8_t} array,
\keyword{char16_t} array,
\keyword{char32_t} array,
or \keyword{wchar_t} array
may be initialized by
an ordinary string literal,
UTF-8 string literal,
UTF-16 string literal,
UTF-32 string literal, or
wide string literal,
respectively, or by an appropriately-typed \grammarterm{string-literal} enclosed in
braces\iref{lex.string}.
Additionally, an array of \keyword{char} or
\tcode{\keyword{unsigned} \keyword{char}}
may be initialized by
a UTF-8 string literal, or by
such a string literal enclosed in braces.
\indextext{initialization!character array}%
Successive
characters of the
value of the \grammarterm{string-literal}
initialize the elements of the array,
with an integral conversion\iref{conv.integral}
if necessary for the source and destination value.
\begin{example}
\begin{codeblock}
char msg[] = "Syntax error on line %s\n";
\end{codeblock}
shows a character array whose members are initialized
with a
\grammarterm{string-literal}.
Note that because
\tcode{'\textbackslash n'}
is a single character and
because a trailing
\tcode{'\textbackslash 0'}
is appended,
\tcode{sizeof(msg)}
is
\tcode{25}.
\end{example}

\pnum
There shall not be more initializers than there are array elements.
\begin{example}
\begin{codeblock}
char cv[4] = "asdf";            // error
\end{codeblock}
is ill-formed since there is no space for the implied trailing
\tcode{'\textbackslash 0'}.
\end{example}

\pnum
If there are fewer initializers than there are array elements, each element not
explicitly initialized shall be zero-initialized\iref{dcl.init}.

\rSec2[dcl.init.ref]{References}%
\indextext{initialization!reference}

\pnum
A variable whose declared type is
``reference to \tcode{T}''\iref{dcl.ref}
shall be initialized.
\begin{example}
\begin{codeblock}
int g(int) noexcept;
void f() {
  int i;
  int& r = i;                   // \tcode{r} refers to \tcode{i}
  r = 1;                        // the value of \tcode{i} becomes \tcode{1}
  int* p = &r;                  // \tcode{p} points to \tcode{i}
  int& rr = r;                  // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i}
  int (&rg)(int) = g;           // \tcode{rg} refers to the function \tcode{g}
  rg(i);                        // calls function \tcode{g}
  int a[3];
  int (&ra)[3] = a;             // \tcode{ra} refers to the array \tcode{a}
  ra[1] = i;                    // modifies \tcode{a[1]}
}
\end{codeblock}
\end{example}

\pnum
A reference cannot be changed to refer to another object after initialization.
\indextext{assignment!reference}%
\begin{note}
Assignment to a reference assigns to the object referred to by the reference\iref{expr.assign}.
\end{note}
\indextext{argument passing!reference and}%
Argument passing\iref{expr.call}
\indextext{\idxcode{return}!reference and}%
and function value return\iref{stmt.return} are initializations.

\pnum
The initializer can be omitted for a reference only in a parameter declaration\iref{dcl.fct},
in the declaration of a function return type, in the declaration of
a class member within its class definition\iref{class.mem}, and where the
\keyword{extern}
specifier is explicitly used.
\indextext{declaration!extern@\tcode{extern} reference}%
\begin{example}
\begin{codeblock}
int& r1;                        // error: initializer missing
extern int& r2;                 // OK
\end{codeblock}
\end{example}

\pnum
Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'',
``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to
``\cvqual{cv2} \tcode{T2}'' if
\tcode{T1} is similar\iref{conv.qual} to \tcode{T2}, or
\tcode{T1} is a base class of \tcode{T2}.
``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible}
with ``\cvqual{cv2} \tcode{T2}'' if
a prvalue of type ``pointer to \cvqual{cv2} \tcode{T2}'' can be converted to
the type ``pointer to \cvqual{cv1} \tcode{T1}''
via a standard conversion sequence\iref{conv}.
In all cases where the reference-compatible relationship
of two types is used to establish the validity of a reference binding and
the standard conversion sequence would be ill-formed,
a program that necessitates such a binding is ill-formed.

\pnum
A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by
an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:%
\indextext{binding!reference}

\begin{itemize}
\item
If the reference is an lvalue reference and the initializer expression
\begin{itemize}
\item
is an lvalue (but is not a
bit-field), and
``\cvqual{cv1} \tcode{T1}'' is reference-compatible with
``\cvqual{cv2} \tcode{T2}'', or
\item
has a class type (i.e.,
\tcode{T2}
is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted
to an lvalue of type ``\cvqual{cv3} \tcode{T3}'', where
``\cvqual{cv1} \tcode{T1}'' is reference-compatible with
``\cvqual{cv3} \tcode{T3}''
\begin{footnote}
This requires a conversion
function\iref{class.conv.fct} returning a reference type.
\end{footnote}
(this conversion is selected by enumerating the applicable conversion
functions\iref{over.match.ref} and choosing the best one through overload
resolution\iref{over.match}),
\end{itemize}
then the reference binds to the initializer expression lvalue in the
first case and to the lvalue result of the conversion
in the second case (or, in either case, to the appropriate base class subobject of the object).
\begin{note}
The usual lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array},
and function-to-pointer\iref{conv.func} standard
conversions are not needed, and therefore are suppressed, when such
direct bindings to lvalues are done.
\end{note}

\begin{example}
\begin{codeblock}
double d = 2.0;
double& rd = d;                 // \tcode{rd} refers to \tcode{d}
const double& rcd = d;          // \tcode{rcd} refers to \tcode{d}

struct A { };
struct B : A { operator int&(); } b;
A& ra = b;                      // \tcode{ra} refers to \tcode{A} subobject in \tcode{b}
const A& rca = b;               // \tcode{rca} refers to \tcode{A} subobject in \tcode{b}
int& ir = B();                  // \tcode{ir} refers to the result of \tcode{B::operator int\&}
\end{codeblock}
\end{example}

\item
Otherwise,
if the reference is an lvalue reference to a
type that is not const-qualified or is volatile-qualified,
the program is ill-formed.
\begin{example}
\begin{codeblock}
double& rd2 = 2.0;              // error: not an lvalue and reference not \keyword{const}
int  i = 2;
double& rd3 = i;                // error: type mismatch and reference not \keyword{const}
\end{codeblock}
\end{example}

\item Otherwise, if the initializer expression
\begin{itemize}
\item is an rvalue (but not a bit-field) or an lvalue of function type and
``\cvqual{cv1} \tcode{T1}'' is
reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or

\item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1}
is not reference-related to \tcode{T2}, and can be converted to
an rvalue of type ``\cvqual{cv3} \tcode{T3}'' or
an lvalue of function type ``\cvqual{cv3} \tcode{T3}'',
where ``\cvqual{cv1} \tcode{T1}'' is
reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}),
\end{itemize}
then
the initializer expression in the first case and
the converted expression in the second case
is called the converted initializer.
If the converted initializer is a prvalue,
let its type be denoted by \tcode{T4};
the temporary materialization conversion\iref{conv.rval} is applied,
considering the type of the prvalue to be
``\cvqual{cv1} \tcode{T4}''\iref{conv.qual}.
In any case,
the reference binds to the resulting glvalue
(or to an appropriate base class subobject).

\begin{example}
\begin{codeblock}
struct A { };
struct B : A { } b;
extern B f();
const A& rca2 = f();                // binds to the \tcode{A} subobject of the \tcode{B} rvalue.
A&& rra = f();                      // same as above
struct X {
  operator B();
  operator int&();
} x;
const A& r = x;                     // binds to the \tcode{A} subobject of the result of the conversion
int i2 = 42;
int&& rri = static_cast<int&&>(i2); // binds directly to \tcode{i2}
B&& rrb = x;                        // binds directly to the result of \tcode{operator B}

constexpr int f() {
  const int &x = 42;
  const_cast<int &>(x) = 1;         // undefined behavior
  return x;
}
constexpr int z = f();              // error: not a constant expression

typedef int *AP[3];                 // array of 3 pointer to \tcode{int}
typedef const int *const ACPC[3];   // array of 3 const pointer to \tcode{const int}
ACPC &&r = AP{};                    // binds directly
\end{codeblock}
\end{example}

\item
Otherwise, \tcode{T1} shall not be reference-related to \tcode{T2}.
\begin{itemize}
\item
If \tcode{T1} or \tcode{T2} is a class type,
user-defined conversions are considered
using the rules for copy-initialization of an object of type
``\cvqual{cv1} \tcode{T1}'' by
user-defined conversion\iref{dcl.init,over.match.copy,over.match.conv};
the program is ill-formed if the corresponding non-reference
copy-initialization would be ill-formed. The result $E$ of the call to the
conversion function, as described for the non-reference
copy-initialization, is then used to direct-initialize the reference
using the form \tcode{($E$)}.
For this direct-initialization, user-defined conversions are not considered.
\item
Otherwise,
the initializer expression is implicitly converted to a prvalue
of type ``\tcode{T1}''.
The temporary materialization conversion is applied,
considering the type of the prvalue to be ``\cvqual{cv1} \tcode{T1}'',
and the reference is bound to the result.
\end{itemize}

\begin{example}
\begin{codeblock}
struct Banana { };
struct Enigma { operator const Banana(); };
struct Alaska { operator Banana&(); };
void enigmatic() {
  typedef const Banana ConstBanana;
  Banana &&banana1 = ConstBanana(); // error
  Banana &&banana2 = Enigma();      // error
  Banana &&banana3 = Alaska();      // error
}

const double& rcd2 = 2;             // \tcode{rcd2} refers to temporary with type \tcode{const double} and value \tcode{2.0}
double&& rrd = 2;                   // \tcode{rrd} refers to temporary with value \tcode{2.0}
const volatile int cvi = 1;
const int& r2 = cvi;                // error: cv-qualifier dropped
struct A { operator volatile int&(); } a;
const int& r3 = a;                  // error: cv-qualifier dropped
                                    // from result of conversion function
double d2 = 1.0;
double&& rrd2 = d2;                 // error: initializer is lvalue of reference-related type
struct X { operator int&(); };
int&& rri2 = X();                   // error: result of conversion function is
                                    // lvalue of reference-related type
int i3 = 2;
double&& rrd3 = i3;                 // \tcode{rrd3} refers to temporary with value \tcode{2.0}
\end{codeblock}
\end{example}
\end{itemize}

In all cases except the last
(i.e., implicitly converting the initializer expression
to the referenced type),
the reference is said to \defn{bind directly} to the
initializer expression.

\pnum
\begin{note}
\ref{class.temporary} describes the lifetime of temporaries bound to references.
\end{note}

\rSec2[dcl.init.list]{List-initialization}%
\indextext{initialization!list-initialization|(}

\pnum
\defnx{List-initialization}{list-initialization} is initialization of an object or reference from a
\grammarterm{braced-init-list}.
Such an initializer is called an \term{initializer list}, and
the comma-separated
\grammarterm{initializer-clause}{s}
of the \grammarterm{initializer-list}
or
\grammarterm{designated-initializer-clause}{s}
of the \grammarterm{designated-initializer-list}
are called the \term{elements} of the initializer list. An initializer list may be empty.
List-initialization can occur in direct-initialization or copy-initialization contexts;
list-initialization in a direct-initialization context is called
\defn{direct-list-initialization} and list-initialization in a
copy-initialization context is called \defn{copy-list-initialization}.
Direct-initialization that is not list-initialization is called
\defn{direct-non-list-initialization}.
\begin{note}
List-initialization can be used
\begin{itemize}
\item as the initializer in a variable definition\iref{dcl.init},
\item as the initializer in a \grammarterm{new-expression}\iref{expr.new},
\item in a \tcode{return} statement\iref{stmt.return},
\item as a \grammarterm{for-range-initializer}\iref{stmt.iter},
\item as a function argument\iref{expr.call},
\item as a template argument\iref{temp.arg.nontype},
\item as a subscript\iref{expr.sub},
\item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv},
\item as an initializer for a non-static data member\iref{class.mem},
\item in a \grammarterm{mem-initializer}\iref{class.base.init}, or
\item on the right-hand side of an assignment\iref{expr.assign}.
\end{itemize}

\begin{example}
\begin{codeblock}
int a = {1};
std::complex<double> z{1,2};
new std::vector<std::string>{"once", "upon", "a", "time"};  // 4 string elements
f( {"Nicholas","Annemarie"} );  // pass list of two elements
return { "Norah" };             // return list of one element
int* e {};                      // initialization to zero / null pointer
x = double{1};                  // explicitly construct a \tcode{double}
std::map<std::string,int> anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} };
\end{codeblock}
\end{example}
\end{note}

\pnum
A constructor is an \defn{initializer-list constructor} if its first parameter is
of type \tcode{std::initializer_list<E>} or reference to
\cv{}~\tcode{std::initializer_list<E>} for some type \tcode{E}, and either there are no other
parameters or else all other parameters have default arguments\iref{dcl.fct.default}.
\begin{note}
Initializer-list constructors are favored over other constructors in
list-initialization\iref{over.match.list}. Passing an initializer list as the argument
to the constructor template \tcode{template<class T> C(T)} of a class \tcode{C} does not
create an initializer-list constructor, because an initializer list argument causes the
corresponding parameter to be a non-deduced context\iref{temp.deduct.call}.
\end{note}
The template
\tcode{std::initializer_list} is not predefined;
if a standard library declaration\iref{initializer.list.syn,std.modules}
of \tcode{std::initializer_list} is not reachable from\iref{module.reach}
a use of \tcode{std::initializer_list} ---
even an implicit use in which the type is not named\iref{dcl.spec.auto} ---
the program is ill-formed.

\pnum
List-initialization of an object or reference of type \cvqual{cv} \tcode{T} is defined as follows:
\begin{itemize}
\item
If the \grammarterm{braced-init-list}
contains a \grammarterm{designated-initializer-list} and
\tcode{T} is not a reference type,
\tcode{T} shall be an aggregate class.
The ordered \grammarterm{identifier}{s}
in the \grammarterm{designator}{s}
of the \grammarterm{designated-initializer-list}
shall form a subsequence
of the ordered \grammarterm{identifier}{s}
in the direct non-static data members of \tcode{T}.
Aggregate initialization is performed\iref{dcl.init.aggr}.
\begin{example}
\begin{codeblock}
struct A { int x; int y; int z; };
A a{.y = 2, .x = 1};                // error: designator order does not match declaration order
A b{.x = 1, .z = 2};                // OK, \tcode{b.y} initialized to \tcode{0}
\end{codeblock}
\end{example}

\item If \tcode{T} is an aggregate class and the initializer list has a single element
of type \cvqual{cv1} \tcode{U},
where \tcode{U} is \tcode{T} or a class derived from \tcode{T},
the object is initialized from that element (by copy-initialization for
copy-list-initialization, or by direct-initialization for
direct-list-initialization).

\item Otherwise, if \tcode{T} is a character array and the initializer list has a
single element that is an appropriately-typed \grammarterm{string-literal}\iref{dcl.init.string},
initialization is performed as described in that subclause.

\item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is
performed\iref{dcl.init.aggr}.

\begin{example}
\begin{codeblock}
double ad[] = { 1, 2.0 };           // OK
int ai[] = { 1, 2.0 };              // error: narrowing

struct S2 {
  int m1;
  double m2, m3;
};
S2 s21 = { 1, 2, 3.0 };             // OK
S2 s22 { 1.0, 2, 3 };               // error: narrowing
S2 s23 { };                         // OK, default to 0,0,0
\end{codeblock}
\end{example}

\item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a
default constructor, the object is value-initialized.

\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list},
the object is constructed as described below.

\item Otherwise, if \tcode{T} is a class type, constructors are considered.
The applicable constructors are enumerated and
the best one is chosen through overload resolution\iref{over.match,over.match.list}. If a narrowing
conversion (see below) is required to convert any of the arguments, the program is
ill-formed.

\begin{example}
\begin{codeblock}
struct S {
  S(std::initializer_list<double>); // \#1
  S(std::initializer_list<int>);    // \#2
  S(std::initializer_list<S>);      // \#3
  S();                              // \#4
  // ...
};
S s1 = { 1.0, 2.0, 3.0 };           // invoke \#1
S s2 = { 1, 2, 3 };                 // invoke \#2
S s3{s2};                           // invoke \#3 (not the copy constructor)
S s4 = { };                         // invoke \#4
\end{codeblock}
\end{example}

\begin{example}
\begin{codeblock}
struct Map {
  Map(std::initializer_list<std::pair<std::string,int>>);
};
Map ship = {{"Sophie",14}, {"Surprise",28}};
\end{codeblock}
\end{example}

\begin{example}
\begin{codeblock}
struct S {
  // no initializer-list constructors
  S(int, double, double);           // \#1
  S();                              // \#2
  // ...
};
S s1 = { 1, 2, 3.0 };               // OK, invoke \#1
S s2 { 1.0, 2, 3 };                 // error: narrowing
S s3 { };                           // OK, invoke \#2
\end{codeblock}
\end{example}

\item Otherwise, if \tcode{T} is an enumeration
with a fixed underlying type\iref{dcl.enum} \tcode{U},
the \grammarterm{initializer-list} has a single element \tcode{v} of scalar type,
\tcode{v} can be implicitly converted to \tcode{U}, and
the initialization is direct-list-initialization,
the object is initialized with the value \tcode{T(v)}\iref{expr.type.conv};
if a narrowing conversion is required to convert \tcode{v}
to \tcode{U}, the program is ill-formed.
\begin{example}
\begin{codeblock}
enum byte : unsigned char { };
byte b { 42 };                      // OK
byte c = { 42 };                    // error
byte d = byte{ 42 };                // OK; same value as \tcode{b}
byte e { -1 };                      // error

struct A { byte b; };
A a1 = { { 42 } };                  // error
A a2 = { byte{ 42 } };              // OK

void f(byte);
f({ 42 });                          // error

enum class Handle : uint32_t { Invalid = 0 };
Handle h { 42 };                    // OK
\end{codeblock}
\end{example}

\item Otherwise, if
the initializer list
is not a \grammarterm{designated-initializer-list} and
has a single element of type \tcode{E} and either
\tcode{T} is not a reference type or its referenced type is
reference-related to \tcode{E}, the object or reference is initialized
from that element (by copy-initialization for copy-list-initialization,
or by direct-initialization for direct-list-initialization);
if a narrowing conversion (see below) is required
to convert the element to \tcode{T}, the program is ill-formed.

\begin{example}
\begin{codeblock}
int x1 {2};                         // OK
int x2 {2.0};                       // error: narrowing
\end{codeblock}
\end{example}

\item Otherwise, if \tcode{T} is a reference type, a prvalue is generated.
The prvalue initializes its result object by copy-list-initialization from the initializer list.
The prvalue is then used to direct-initialize the reference.
The type of the prvalue is the type referenced by \tcode{T},
unless \tcode{T} is ``reference to array of unknown bound of \tcode{U}'',
in which case the type of the prvalue is
the type of \tcode{x} in the declaration \tcode{U x[] $H$},
where $H$ is the initializer list.
\begin{note}
As usual, the binding will fail and the program is ill-formed if
the reference type is an lvalue reference to a non-const type.
\end{note}

\begin{example}
\begin{codeblock}
struct S {
  S(std::initializer_list<double>); // \#1
  S(const std::string&);            // \#2
  // ...
};
const S& r1 = { 1, 2, 3.0 };        // OK, invoke \#1
const S& r2 { "Spinach" };          // OK, invoke \#2
S& r3 = { 1, 2, 3 };                // error: initializer is not an lvalue
const int& i1 = { 1 };              // OK
const int& i2 = { 1.1 };            // error: narrowing
const int (&iar)[2] = { 1, 2 };     // OK, \tcode{iar} is bound to temporary array

struct A { } a;
struct B { explicit B(const A&); };
const B& b2{a};                     // error: cannot copy-list-initialize \tcode{B} temporary from \tcode{A}

struct C { int x; };
C&& c = { .x = 1 };                 // OK
\end{codeblock}
\end{example}

\item Otherwise, if the initializer list has no elements, the object is
value-initialized.

\begin{example}
\begin{codeblock}
int** pp {};                        // initialized to null pointer
\end{codeblock}
\end{example}

\item Otherwise, the program is ill-formed.

\begin{example}
\begin{codeblock}
struct A { int i; int j; };
A a1 { 1, 2 };                      // aggregate initialization
A a2 { 1.2 };                       // error: narrowing
struct B {
  B(std::initializer_list<int>);
};
B b1 { 1, 2 };                      // creates \tcode{initializer_list<int>} and calls constructor
B b2 { 1, 2.0 };                    // error: narrowing
struct C {
  C(int i, double j);
};
C c1 = { 1, 2.2 };                  // calls constructor with arguments (1, 2.2)
C c2 = { 1.1, 2 };                  // error: narrowing

int j { 1 };                        // initialize to 1
int k { };                          // initialize to 0
\end{codeblock}
\end{example}

\end{itemize}

\pnum
Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list},
the \grammarterm{initializer-clause}{s}, including any that result from pack
expansions\iref{temp.variadic}, are evaluated in the order in which they
appear. That is, every value computation and side effect associated with a
given \grammarterm{initializer-clause} is sequenced before every value
computation and side effect associated with any \grammarterm{initializer-clause}
that follows it in the comma-separated list of the \grammarterm{initializer-list}.
\begin{note}
This evaluation ordering holds regardless of the semantics of the
initialization; for example, it applies when the elements of the
\grammarterm{initializer-list} are interpreted as arguments of a constructor
call, even though ordinarily there are no sequencing constraints on the
arguments of a call.
\end{note}

\pnum
An object of type \tcode{std::initializer_list<E>} is constructed from
an initializer list as if
the implementation generated and materialized\iref{conv.rval}
a prvalue of type ``array of $N$ \tcode{const E}'',
where $N$ is the number of elements in the initializer list;
this is called the initializer list's \defnadj{backing}{array}.
Each element of the backing array is copy-initialized with the
corresponding element of the initializer list, and the
\tcode{std::initializer_list<E>} object is constructed to refer to that array.
\begin{note}
A constructor or conversion function selected for the copy needs to be
accessible\iref{class.access} in the context of the initializer list.
\end{note}
If a narrowing conversion is required to initialize any of the elements,
the program is ill-formed.
\begin{note}
Backing arrays are potentially non-unique objects\iref{intro.object}.
\end{note}

\pnum
The backing array has the same lifetime as any other temporary
object\iref{class.temporary}, except that initializing an
\tcode{initializer_list} object from the array extends the lifetime of
the array exactly like binding a reference to a temporary.
\begin{example}
\begin{codeblock}
void f(std::initializer_list<double> il);
void g(float x) {
  f({1, x, 3});
}
void h() {
  f({1, 2, 3});
}

struct A {
  mutable int i;
};
void q(std::initializer_list<A>);
void r() {
  q({A{1}, A{2}, A{3}});
}
\end{codeblock}

The initialization will be implemented in a way roughly equivalent to this:
\begin{codeblock}
void g(float x) {
  const double __a[3] = {double{1}, double{x}, double{3}};              // backing array
  f(std::initializer_list<double>(__a, __a+3));
}
void h() {
  static constexpr double __b[3] = {double{1}, double{2}, double{3}};   // backing array
  f(std::initializer_list<double>(__b, __b+3));
}
void r() {
  const A __c[3] = {A{1}, A{2}, A{3}};                                  // backing array
  q(std::initializer_list<A>(__c, __c+3));
}
\end{codeblock}
assuming that the implementation
can construct an \tcode{initializer_list} object with a pair of pointers, and
with the understanding that \tcode{__b} does not outlive the call to \tcode{f}.
\end{example}

\begin{example}
\begin{codeblock}
typedef std::complex<double> cmplx;
std::vector<cmplx> v1 = { 1, 2, 3 };

void f() {
  std::vector<cmplx> v2{ 1, 2, 3 };
  std::initializer_list<int> i3 = { 1, 2, 3 };
}

struct A {
  std::initializer_list<int> i4;
  A() : i4{ 1, 2, 3 } {}            // ill-formed, would create a dangling reference
};
\end{codeblock}

For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object
is a parameter in a function call, so the array created for
\tcode{\{ 1, 2, 3 \}} has full-expression lifetime.
For \tcode{i3}, the \tcode{initializer_list} object is a variable,
so the array persists for the lifetime of the variable.
For \tcode{i4}, the \tcode{initializer_list} object is initialized in
the constructor's \grammarterm{ctor-initializer} as if by binding
a temporary array to a reference member, so the program is
ill-formed\iref{class.base.init}.
\end{example}

\pnum
A \defnadj{narrowing}{conversion} is an implicit conversion
\begin{itemize}
\item from a floating-point type to an integer type, or

\item from a floating-point type \tcode{T} to another floating-point type
whose floating-point conversion rank is neither greater than nor equal to
that of \tcode{T},
except where the result of the conversion is a constant expression and
either its value is finite and the conversion did not overflow, or
the values before and after the conversion are not finite, or

\item from an integer type or unscoped enumeration type to a floating-point type, except
where the source is a constant expression and the actual value after conversion will fit
into the target type and will produce the original value when converted back to the
original type, or

\item from an integer type or unscoped enumeration type to an integer type that cannot
represent all the values of the original type, except where
\begin{itemize}
\item
the source is a bit-field whose width $w$ is less than that of its type
(or, for an enumeration type, its underlying type) and
the target type can represent all the values
of a hypothetical extended integer type
with width $w$ and with the same signedness as the original type or
\item
the source is a constant
expression whose value after integral promotions will fit into the target type, or
\end{itemize}

\item from a pointer type or a pointer-to-member type to \tcode{bool}.
\end{itemize}

\begin{note}
As indicated above, such conversions are not allowed at the top level in
list-initializations.
\end{note}
\begin{example}
\begin{codeblock}
int x = 999;                    // \tcode{x} is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x;                    // OK, though it potentially narrows (in this case, it does narrow)
char c2{x};                     // error: potentially narrows
char c3{y};                     // error: narrows (assuming \tcode{char} is 8 bits)
char c4{z};                     // OK, no narrowing needed
unsigned char uc1 = {5};        // OK, no narrowing needed
unsigned char uc2 = {-1};       // error: narrows
unsigned int ui1 = {-1};        // error: narrows
signed int si1 =
  { (unsigned int)-1 };         // error: narrows
int ii = {2.0};                 // error: narrows
float f1 { x };                 // error: potentially narrows
float f2 { 7 };                 // OK, 7 can be exactly represented as a \tcode{float}
bool b = {"meow"};              // error: narrows
int f(int);
int a[] = { 2, f(2), f(2.0) };  // OK, the \tcode{double}-to-\tcode{int} conversion is not at the top level
\end{codeblock}
\end{example}
\indextext{initialization!list-initialization|)}%
\indextext{initialization|)}%
\indextext{declarator|)}

\rSec1[dcl.fct.def]{Function definitions}%
\indextext{definition!function|(}

\rSec2[dcl.fct.def.general]{General}

\pnum
\indextext{body!function}%
Function definitions have the form
\indextext{\idxgram{function-definition}}%
%
\begin{bnf}
\nontermdef{function-definition}\br
    \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq}\br
    \bnfindent \opt{function-contract-specifier-seq} function-body\br
    \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause\br
    \bnfindent \opt{function-contract-specifier-seq} function-body
\end{bnf}

\begin{bnf}
\nontermdef{function-body}\br
    \opt{ctor-initializer} compound-statement\br
    function-try-block\br
    \terminal{=} \keyword{default} \terminal{;}\br
    deleted-function-body
\end{bnf}

\begin{bnf}
\nontermdef{deleted-function-body}\br
    \terminal{=} \keyword{delete} \terminal{;}\br
    \terminal{=} \keyword{delete} \terminal{(} unevaluated-string \terminal{)} \terminal{;}
\end{bnf}

Any informal reference to the body of a function should be interpreted as a reference to
the non-terminal \grammarterm{function-body},
including, for a constructor,
default member initializers or default initialization
used to initialize
a base or member subobject in the absence of
a \grammarterm{mem-initializer-id}\iref{class.base.init}.
The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition}
appertains to the function.
A \grammarterm{function-definition} with a \grammarterm{virt-specifier-seq}
shall be a \grammarterm{member-declaration}\iref{class.mem}.
A \grammarterm{function-definition} with a \grammarterm{requires-clause}
shall define a templated function.

\pnum
In a \grammarterm{function-definition},
either \keyword{void} \grammarterm{declarator} \tcode{;}
or \grammarterm{declarator} \tcode{;}
shall be a well-formed function declaration
as described in~\ref{dcl.fct}.
A function shall be defined only in namespace or class scope.
The type of a parameter or the return type for a function
definition shall not be
a (possibly cv-qualified) class type that is
incomplete or abstract within the function body
unless the function is deleted\iref{dcl.fct.def.delete}.

\pnum
\begin{example}
A simple example of a complete function definition is
\begin{codeblock}
int max(int a, int b, int c) {
  int m = (a > b) ? a : b;
  return (m > c) ? m : c;
}
\end{codeblock}

Here
\tcode{int}
is the
\grammarterm{decl-specifier-seq};
\tcode{max(int}
\tcode{a,}
\tcode{int}
\tcode{b,}
\tcode{int}
\tcode{c)}
is the
\grammarterm{declarator};
\tcode{\{ \commentellip{} \}}
is the
\grammarterm{function-body}.
\end{example}

\pnum
\indextext{initializer!base class}%
\indextext{initializer!member}%
\indextext{definition!constructor}%
A
\grammarterm{ctor-initializer}
is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}.

\pnum
\begin{note}
A \grammarterm{cv-qualifier-seq} affects the type of \keyword{this}
in the body of a member function; see~\ref{expr.prim.this}.
\end{note}

\pnum
\begin{note}
Unused parameters need not be named.
For example,

\begin{codeblock}
void print(int a, int) {
  std::printf("a = %d\n",a);
}
\end{codeblock}
\end{note}

\pnum
A \defnadj{function-local predefined}{variable} is a variable with static
storage duration that is implicitly defined in a function parameter scope.

\pnum
\indextext{__func__@\mname{func}}%
The function-local predefined variable \mname{func} is
defined as if a definition of the form
\begin{codeblock}
static const char __func__[] = "@\placeholder{function-name}@";
\end{codeblock}
had been provided, where \tcode{\placeholder{function-name}} is an \impldef{string resulting
from \mname{func}} string.
It is unspecified whether such a variable has an address
distinct from that of any other object in the program.
\begin{footnote}
Implementations are
permitted to provide additional predefined variables with names that are reserved to the
implementation\iref{lex.name}. If a predefined variable is not
odr-used\iref{term.odr.use}, its string value need not be present in the program image.
\end{footnote}
\begin{example}
\begin{codeblock}
struct S {
  S() : s(__func__) { }             // OK
  const char* s;
};
void f(const char* s = __func__);   // error: \mname{func} is undeclared
\end{codeblock}
\end{example}

\rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}%

\pnum
A function definition whose
\grammarterm{function-body}
is of the form
\tcode{= default ;}
is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition.
A function that is explicitly defaulted shall
\begin{itemize}
\item be a special member function\iref{special} or
a comparison operator function\iref{over.binary, class.compare.default}, and
\item not have default arguments\iref{dcl.fct.default}.
\end{itemize}

\pnum
An explicitly defaulted special member function $\tcode{F}_1$
is allowed to differ from
the corresponding special member function $\tcode{F}_2$
that would have been implicitly declared, as follows:
\begin{itemize}
\item
  $\tcode{F}_1$ and $\tcode{F}_2$ may have differing \grammarterm{ref-qualifier}{s};
\item
  if $\tcode{F}_2$ has an implicit object parameter of
  type ``reference to \tcode{C}'',
  $\tcode{F}_1$ may be an explicit object member function whose
  explicit object parameter is of (possibly different) type ``reference to \tcode{C}'',
  in which case the type of $\tcode{F}_1$ would differ from the type of $\tcode{F}_2$
  in that the type of $\tcode{F}_1$ has an additional parameter;
\item
  $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; and
\item
  if $\tcode{F}_2$ has a non-object parameter of type \tcode{const C\&},
  the corresponding non-object parameter of $\tcode{F}_1$ may be of
  type \tcode{C\&}.
\end{itemize}
If the type of $\tcode{F}_1$ differs from the type of $\tcode{F}_2$ in a way
other than as allowed by the preceding rules, then:
\begin{itemize}
\item
  if $\tcode{F}_1$ is an assignment operator, and
  the return type of $\tcode{F}_1$ differs from
  the return type of $\tcode{F}_2$ or
  $\tcode{F}_1${'s} non-object parameter type is not a reference,
  the program is ill-formed;
\item
  otherwise, if $\tcode{F}_1$ is explicitly defaulted on its first declaration,
  it is defined as deleted;
\item
  otherwise, the program is ill-formed.
\end{itemize}

\pnum
A function explicitly defaulted on its first declaration
is implicitly inline\iref{dcl.inline},
and is implicitly constexpr\iref{dcl.constexpr}
if it is constexpr-suitable.
\begin{note}
Other defaulted functions are not implicitly constexpr.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
struct S {
  S(int a = 0) = default;               // error: default argument
  void operator=(const S&) = default;   // error: non-matching return type
  ~S() noexcept(false) = default;       // OK, despite mismatched exception specification
private:
  int i;
  S(S&);                                // OK, private copy constructor
};
S::S(S&) = default;                     // OK, defines copy constructor

struct T {
  T();
  T(T &&) noexcept(false);
};
struct U {
  T t;
  U();
  U(U &&) noexcept = default;
};
U u1;
U u2 = static_cast<U&&>(u1);            // OK, calls \tcode{std::terminate} if \tcode{T::T(T\&\&)} throws
\end{codeblock}
\end{example}

\pnum
Explicitly-defaulted functions and implicitly-declared functions are collectively
called \defn{defaulted} functions, and the implementation
shall provide implicit definitions
for them\iref{class.ctor,class.dtor,class.copy.ctor,class.copy.assign} as described below,
including possibly defining them as deleted.
A defaulted prospective destructor\iref{class.dtor}
that is not a destructor is defined as deleted.
A defaulted special member function
that is neither a prospective destructor nor
an eligible special member function\iref{special}
is defined as deleted.
A function is
\defn{user-provided} if it is user-declared and not explicitly
defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function
(i.e., explicitly defaulted after its first declaration)
is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly
defined as deleted, the program is ill-formed.
\begin{note}
Declaring a function as defaulted after its first declaration
can provide efficient execution and concise definition
while enabling a stable binary interface to an evolving code base.
\end{note}
A non-user-provided defaulted function
(i.e., implicitly declared or explicitly defaulted in the class)
that is not defined as deleted is implicitly defined when it is odr-used\iref{basic.def.odr}
or needed for constant evaluation\iref{expr.const.defns}.
\begin{note}
The implicit definition of a non-user-provided defaulted function
does not bind any names.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
struct trivial {
  trivial() = default;
  trivial(const trivial&) = default;
  trivial(trivial&&) = default;
  trivial& operator=(const trivial&) = default;
  trivial& operator=(trivial&&) = default;
  ~trivial() = default;
};

struct nontrivial1 {
  nontrivial1();
};
nontrivial1::nontrivial1() = default;   // not first declaration
\end{codeblock}
\end{example}

\rSec2[dcl.fct.def.delete]{Deleted definitions}%
\indextext{definition!function!deleted}%

\pnum
A \defnadj{deleted}{definition} of a function is a function definition
whose \grammarterm{function-body} is a \grammarterm{deleted-function-body}
or an explicitly-defaulted definition of the function where the function is
defined as deleted.
A \defnadj{deleted}{function} is
a function with a
deleted definition or a function that is implicitly defined as deleted.

\pnum
A construct that designates a deleted function implicitly or explicitly,
other than to declare it or to appear as the operand of
a \grammarterm{reflect-expression}\iref{expr.reflect},
is ill-formed.

\recommended
The resulting diagnostic message should include
the text of the \grammarterm{unevaluated-string},
if one is supplied.

\begin{note}
This includes calling the function
implicitly or explicitly and forming a pointer or pointer-to-member to the
function. It applies even for references in expressions that are not
potentially evaluated. For an overload set, only the
function selected by overload resolution is referenced. The implicit
odr-use\iref{term.odr.use} of a virtual function does not, by itself,
constitute a reference.
The \grammarterm{unevaluated-string}, if present,
can be used to explain the rationale for deletion and/or
to suggest an alternative.
\end{note}

\pnum
\begin{example}
One can prevent default initialization and
initialization by non-\tcode{double}s with
\begin{codeblock}
struct onlydouble {
  onlydouble() = delete;                // OK, but redundant
  template<class T>
    onlydouble(T) = delete;
  onlydouble(double);
};
\end{codeblock}
\end{example}

\begin{example}
One can prevent use of a
class in certain \grammarterm{new-expression}{s} by using deleted definitions
of a user-declared \tcode{operator new} for that class.
\begin{codeblock}
struct sometype {
  void* operator new(std::size_t) = delete;
  void* operator new[](std::size_t) = delete;
};
sometype* p = new sometype;     // error: deleted class \tcode{operator new}
sometype* q = new sometype[3];  // error: deleted class \tcode{operator new[]}
\end{codeblock}
\end{example}

\begin{example}
One can make a class uncopyable, i.e., move-only, by using deleted
definitions of the copy constructor and copy assignment operator, and then
providing defaulted definitions of the move constructor and move assignment operator.
\begin{codeblock}
struct moveonly {
  moveonly() = default;
  moveonly(const moveonly&) = delete;
  moveonly(moveonly&&) = default;
  moveonly& operator=(const moveonly&) = delete;
  moveonly& operator=(moveonly&&) = default;
  ~moveonly() = default;
};
moveonly* p;
moveonly q(*p);                 // error: deleted copy constructor
\end{codeblock}
\end{example}

\pnum
A deleted function is implicitly an inline function\iref{dcl.inline}.
\begin{note}
The
one-definition rule\iref{basic.def.odr} applies to deleted definitions.
\end{note}
A deleted definition of a function shall be the first declaration of the function or,
for an explicit specialization of a function template, the first declaration of that
specialization.
An implicitly declared allocation or deallocation function\iref{basic.stc.dynamic}
shall not be defined as deleted.
\begin{example}
\begin{codeblock}
struct sometype {
  sometype();
};
sometype::sometype() = delete;  // error: not first declaration
\end{codeblock}
\end{example}
\indextext{definition!function|)}

\rSec2[dcl.fct.def.coroutine]{Coroutine definitions}%
\indextext{definition!coroutine}%

\pnum
A function is a \defn{coroutine} if its \grammarterm{function-body} encloses a
\grammarterm{coroutine-return-statement}\iref{stmt.return.coroutine},
an \grammarterm{await-expression}\iref{expr.await},
or a \grammarterm{yield-expression}\iref{expr.yield}.
The \grammarterm{parameter-declaration-clause} of the coroutine shall not
terminate with an ellipsis that is not part of
a \grammarterm{parameter-declaration}.

\pnum
\begin{example}
\begin{codeblock}
task<int> f();

task<void> g1() {
  int i = co_await f();
  std::cout << "f() => " << i << std::endl;
}

template <typename... Args>
task<void> g2(Args&&...) {      // OK, ellipsis is a pack expansion
  int i = co_await f();
  std::cout << "f() => " << i << std::endl;
}

task<void> g3(int a, ...) {     // error: variable parameter list not allowed
  int i = co_await f();
  std::cout << "f() => " << i << std::endl;
}
\end{codeblock}
\end{example}

\pnum
\indextext{promise type|see{coroutine, promise type}}%
The \defnx{promise type}{coroutine!promise type} of a coroutine is
\tcode{std::coroutine_traits<R, P$_1$, $\dotsc$, P$_n$>::promise_type},
where
\tcode{R} is the return type of the function, and
$\tcode{P}_1 \dotsc \tcode{P}_n$ is the sequence of types of the non-object function parameters,
preceded by the type of the object parameter\iref{dcl.fct}
if the coroutine is a non-static member function.
The promise type shall be a class type.

\pnum
In the following, $\tcode{p}_i$ is an lvalue of type $\tcode{P}_i$,
where
$\tcode{p}_1$ denotes the object parameter and
$\tcode{p}_{i+1}$ denotes the $i^\text{th}$ non-object function parameter
for an implicit object member function, and
$\tcode{p}_i$ denotes
the $i^\text{th}$ function parameter otherwise.
For an implicit object member function,
$\tcode{q}_1$ is an lvalue that denotes \tcode{*this};
any other $\tcode{q}_i$ is an lvalue
that denotes the parameter copy corresponding to $\tcode{p}_i$,
as described below.

\pnum
A coroutine behaves as if
the top-level cv-qualifiers in all
\grammarterm{parameter-declaration}s in the declarator
of its \grammarterm{function-definition}
were removed and
its \grammarterm{function-body} were replaced by
the following \defnadj{replacement}{body}:
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent \placeholder{promise-type} \exposid{promise} \placeholder{promise-constructor-arguments} \terminal{;}\br
% FIXME: \bnfindent \exposid{promise}\terminal{.get_return_object()} \terminal{;}
% ... except that it's not a discarded-value expression
\bnfindent \terminal{try} \terminal{\{}\br
\bnfindent\bnfindent \terminal{co_await} \terminal{\exposid{promise}.initial_suspend()} \terminal{;}\br
\bnfindent\bnfindent function-body\br
\bnfindent \terminal{\} catch ( ... ) \{}\br
\bnfindent\bnfindent \terminal{if (!\exposid{initial-await-resume-called})}\br
\bnfindent\bnfindent\bnfindent \terminal{throw} \terminal{;}\br
\bnfindent\bnfindent \terminal{\exposid{promise}.unhandled_exception()} \terminal{;}\br
\bnfindent \terminal{\}}\br
\exposid{final-suspend} \terminal{:}\br
\bnfindent \terminal{co_await} \terminal{\exposid{promise}.final_suspend()} \terminal{;}\br
\terminal{\}}
\end{ncsimplebnf}
where
\begin{itemize}
\item
\indextext{coroutine!await expression}%
the \grammarterm{await-expression} containing
the call to \tcode{initial_suspend}
is the \defnadj{initial}{await expression}, and
\item
the \grammarterm{await-expression} containing
the call to \tcode{final_suspend}
is the \defnadj{final}{await expression}, and
\item
\placeholder{initial-await-resume-called}
is initially \tcode{false} and is set to \tcode{true}
immediately before the evaluation
of the \placeholder{await-resume} expression\iref{expr.await}
of the initial await expression, and
\item
\placeholder{promise-type} denotes the promise type, and
\item
the object denoted by the exposition-only name \exposid{promise}
is the \defn{promise object} of the coroutine, and
\item
the label denoted by the name \exposid{final-suspend}
is defined for exposition only\iref{stmt.return.coroutine}, and
\item
\placeholder{promise-constructor-arguments} is determined as follows:
overload resolution is performed on a promise constructor call created by
assembling an argument list $\tcode{q}_1 \dotsc \tcode{q}_n$. If a viable
constructor is found\iref{over.match.viable}, then
\placeholder{promise-constructor-arguments} is
\tcode{($\tcode{q}_1$, $\dotsc$, $\tcode{q}_n$)}, otherwise
\placeholder{promise-constructor-arguments} is empty, and
\item
a coroutine is suspended at the \defnadj{initial}{suspend point} if
it is suspended at the initial await expression, and
\item
a coroutine is suspended at a \defnadj{final}{suspend point} if
it is suspended
\begin{itemize}
\item
at a final await expression or
\item
due to an exception exiting from \tcode{unhandled_exception()}.
\end{itemize}
\end{itemize}

\pnum
\begin{note}
An odr-use of a non-reference parameter
in a postcondition assertion
of a coroutine is ill-formed\iref{dcl.contract.func}.
\end{note}

\pnum
If searches for the names \tcode{return_void} and \tcode{return_value}
in the scope of the promise type each find any declarations,
the program is ill-formed.
\begin{note}
If \tcode{return_void} is found, flowing off
the end of a coroutine is equivalent to a \keyword{co_return} with no operand.
Otherwise, flowing off the end of a coroutine
results in undefined behavior\iref{stmt.return.coroutine}.
\end{note}

\pnum
The expression \tcode{\exposid{promise}.get_return_object()} is used
to initialize
the returned reference or prvalue result object of a call to a coroutine.
The call to \tcode{get_return_object}
is sequenced before
the call to \tcode{initial_suspend}
and is invoked at most once.

\pnum
A suspended coroutine can be resumed to continue execution by invoking
a resumption member function\iref{coroutine.handle.resumption}
of a coroutine handle\iref{coroutine.handle}
that refers to the coroutine.
The evaluation that invoked a resumption member function is
called the \defnx{resumer}{coroutine!resumer}.
Invoking a resumption member function for a coroutine
that is not suspended results in undefined behavior.

\pnum
An implementation may need to allocate additional storage for a coroutine.
This storage is known as the \defn{coroutine state} and is obtained by calling
a non-array allocation function\iref{basic.stc.dynamic.allocation}
as part of the replacement body.
The allocation function's name is looked up by searching for it in the scope of the promise type.
\begin{itemize}
\item
If the search finds any declarations,
overload resolution is performed on a function call created by assembling an
argument list. The first argument is the amount of space requested, and
is a prvalue of type \tcode{std::size_t}.
The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$
with their original types (including cv-qualifiers)
are the successive arguments.
If no viable function is found\iref{over.match.viable},
overload resolution is performed again
on a function call created by passing just
the amount of space required as a prvalue of type \tcode{std::size_t}.
\item
If the search finds no declarations, a search is performed in the global scope.
Overload resolution is performed on a function call created by
passing the amount of space required as a prvalue of type \tcode{std::size_t}.
\end{itemize}

\pnum
If a search for the name \tcode{get_return_object_on_allocation_failure}
in the scope of the promise type\iref{class.member.lookup} finds
any declarations, then the result
of a call to an allocation function used to obtain storage for the coroutine
state is assumed to return \keyword{nullptr} if it fails to obtain storage,
and if a global allocation function is selected,
the \tcode{::operator new(size_t, nothrow_t)} form is used.
The allocation function used in this case shall have a non-throwing
\grammarterm{noexcept-specifier}.
If the allocation function returns \keyword{nullptr}, the coroutine transfers
control to the caller of the coroutine and the return value is obtained by a
call to \tcode{T::get_return_object_on_allocation_failure()}, where \tcode{T}
is the promise type.

\begin{example}
\begin{codeblock}
#include <iostream>
#include <coroutine>

// \tcode{::operator new(size_t, nothrow_t)} will be used if allocation is needed
struct generator {
  struct promise_type;
  using handle = std::coroutine_handle<promise_type>;
  struct promise_type {
    int current_value;
    static auto get_return_object_on_allocation_failure() { return generator{nullptr}; }
    auto get_return_object() { return generator{handle::from_promise(*this)}; }
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    void unhandled_exception() { std::terminate(); }
    void return_void() {}
    auto yield_value(int value) {
      current_value = value;
      return std::suspend_always{};
    }
  };
  bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; }
  int current_value() { return coro.promise().current_value; }
  generator(generator const&) = delete;
  generator(generator && rhs) : coro(rhs.coro) { rhs.coro = nullptr; }
  ~generator() { if (coro) coro.destroy(); }
private:
  generator(handle h) : coro(h) {}
  handle coro;
};
generator f() { co_yield 1; co_yield 2; }
int main() {
  auto g = f();
  while (g.move_next()) std::cout << g.current_value() << std::endl;
}
\end{codeblock}
\end{example}

\pnum
The coroutine state is destroyed when control flows off the end of the
coroutine or the \tcode{destroy} member
function\iref{coroutine.handle.resumption}
of a coroutine handle\iref{coroutine.handle}
that refers to the coroutine
is invoked.
In the latter case,
control in the coroutine is considered
to be transferred out of the function\iref{stmt.dcl}.
The storage for the coroutine state is released by calling a
non-array deallocation function\iref{basic.stc.dynamic.deallocation}.
If \tcode{destroy} is called for a coroutine that is not suspended, the
program has undefined behavior.

\pnum
The deallocation function's name is looked up by searching for it in the scope of the promise type.
If nothing is found, a search is performed in the
global scope. If both a usual deallocation
function with only a pointer parameter and a usual deallocation function with
both a pointer parameter and a size parameter are found, then the selected deallocation
function shall be the one with two parameters. Otherwise, the selected
deallocation function shall be the function with one parameter. If no usual
deallocation function is found, the program is ill-formed.
The selected deallocation function shall be called with the address of the
block of storage to be reclaimed as its first argument. If a deallocation
function with a parameter of type \tcode{std::size_t} is used, the size of
the block is passed as the corresponding argument.

\pnum
When a coroutine is invoked,
a copy is created for each coroutine parameter
at the beginning of the replacement body.
For a parameter
whose original declaration specified the type \cv{}~\tcode{T},
\begin{itemize}
\item
if \tcode{T} is a reference type,
the copy is a reference of type
\cv{}~\tcode{T}
bound to the same object as a parameter;
\item
otherwise, the copy is a variable
of type \cv{}~\tcode{T}
with automatic storage duration that is direct-initialized
from an xvalue of type \tcode{T} referring to the parameter.
\end{itemize}
\begin{note}
An identifier in the \grammarterm{function-body}
that names one of these parameters
refers to the created copy,
not the original parameter\iref{expr.prim.id.unqual}.
\end{note}

The initialization and destruction of each parameter copy occurs in the
context of the called coroutine.
Initializations of parameter copies are sequenced before the call to the
coroutine promise constructor and indeterminately sequenced with respect to
each other.
The lifetime of parameter copies ends immediately after the lifetime of the
coroutine promise object ends.
\begin{note}
If a coroutine has a parameter passed by reference, resuming the coroutine
after the lifetime of the entity referred to by that parameter has ended is
likely to result in undefined behavior.
\end{note}

\pnum
If the evaluation of the expression
\tcode{\exposid{promise}.unhandled_exception()} exits via an exception,
the coroutine is considered suspended at the final suspend point
and the exception propagates to the caller or resumer.

\pnum
The expression \keyword{co_await} \tcode{\exposid{promise}.final_suspend()}
shall not be potentially-throwing\iref{except.spec}.

\rSec2[dcl.fct.def.replace]{Replaceable function definitions}

\indextext{function!replaceable|(}%
\indextext{replaceable!function|see{function, replaceable}}%

\pnum
\label{term.replaceable.function}%
Certain functions
for which a definition is supplied by the implementation
are \defnx{replaceable}{function!replaceable}.
A \Cpp{} program may
provide a definition with the signature of a replaceable function,
called a \defnadj{replacement}{function}.
The replacement function
is used instead of the default version
supplied by the implementation.
Such replacement occurs
prior to program startup\iref{basic.def.odr,basic.start}.
A declaration of the replacement function
\begin{itemize}
\item
shall not be inline,
\item
shall be attached to the global module,
\item
shall have \Cpp{} language linkage,
\item
shall have the same return type as the replaceable function, and
\item
if the function is declared in a standard library header,
shall be such that it would be valid as a redeclaration
of the declaration in that header;
\end{itemize}
no diagnostic is required.
\begin{note}
The one-definition rule\iref{basic.def.odr}
applies to the definitions of a replaceable function
provided by the program.
The implementation-supplied function definition
is an otherwise-unnamed function with no linkage.
\end{note}
\indextext{function!replaceable|)}%

\rSec1[dcl.struct.bind]{Structured binding declarations}%
\indextext{structured binding declaration}%
\indextext{declaration!structured binding|see{structured binding declaration}}%

\pnum
A structured binding declaration introduces the \grammarterm{identifier}{s}
$\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc, \tcode{v}_{N-1}$
of the
\grammarterm{sb-identifier-list} as names.
An \grammarterm{sb-identifier} that contains an ellipsis
introduces a structured binding pack\iref{temp.variadic}.
A \defn{structured binding} is either
an \grammarterm{sb-identifier} that does not contain an ellipsis or
an element of a structured binding pack.
The optional \grammarterm{attribute-specifier-seq} of
an \grammarterm{sb-identifier}
appertains to the associated structured bindings.
Let \cv{} denote the \grammarterm{cv-qualifier}{s} in
the \grammarterm{decl-specifier-seq} and
\placeholder{S} consist of
each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq}
that is \tcode{constexpr}, \tcode{constinit}, or
a \grammarterm{storage-class-specifier}.
A \cv{} that includes \tcode{volatile} is deprecated;
see~\ref{depr.volatile.type}.
First, a variable with a unique name \exposid{e} is introduced. If the
\grammarterm{assignment-expression} in the \grammarterm{initializer}
has array type \cvqual{cv1} \tcode{A} and no \grammarterm{ref-qualifier} is present,
\exposid{e} is defined by
\begin{ncbnf}
\opt{attribute-specifier-seq} \placeholder{S} \cv{} \terminal{A} \exposid{e} \terminal{;}
\end{ncbnf}
and each element is copy-initialized or direct-initialized
from the corresponding element of the \grammarterm{assignment-expression} as specified
by the form of the \grammarterm{initializer}.
Otherwise, \exposid{e}
is defined as-if by
\begin{ncbnf}
\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \exposid{e} initializer \terminal{;}
\end{ncbnf}
where
the declaration is never interpreted as a function declaration and
the parts of the declaration other than the \grammarterm{declarator-id} are taken
from the corresponding structured binding declaration.
The type of the \grammarterm{id-expression}
\exposid{e} is called \tcode{E}.
\begin{note}
\tcode{E} is never a reference type\iref{expr.prop}.
\end{note}

\pnum
The \defn{structured binding size} of \tcode{E}, as defined below,
is the number of structured bindings
that need to be introduced by the structured binding declaration.
If there is no structured binding pack,
then the number of elements in the \grammarterm{sb-identifier-list}
shall be equal to the structured binding size of \tcode{E}.
Otherwise, the number of non-pack elements shall be no more than
the structured binding size of \tcode{E};
the number of elements of the structured binding pack is
the structured binding size of \tcode{E} less
the number of non-pack elements in the \grammarterm{sb-identifier-list}.

\pnum
Let $\textrm{SB}_i$ denote
the $i^\textrm{th}$ structured binding in the structured binding declaration
after expanding the structured binding pack, if any.
\begin{note}
If there is no structured binding pack,
then $\textrm{SB}_i$ denotes $\tcode{v}_i$.
\end{note}
\begin{example}
\begin{codeblock}
struct C { int x, y, z; };

template<class T>
void now_i_know_my() {
  auto [a, b, c] = C();     // OK, $\textrm{SB}_0$ is \tcode{a}, $\textrm{SB}_1$ is \tcode{b}, and $\textrm{SB}_2$ is \tcode{c}
  auto [d, ...e] = C();     // OK, $\textrm{SB}_0$ is \tcode{d}, the pack \tcode{e} $(\tcode{v}_1)$ contains two structured bindings: $\textrm{SB}_1$ and $\textrm{SB}_2$
  auto [...f, g] = C();     // OK, the pack \tcode{f} $(\tcode{v}_0)$ contains two structured bindings: $\textrm{SB}_0$ and $\textrm{SB}_1$, and $\textrm{SB}_2$ is \tcode{g}
  auto [h, i, j, ...k] = C();           // OK, the pack \tcode{k} is empty
  auto [l, m, n, o, ...p] = C();        // error: structured binding size is too small
}
\end{codeblock}
\end{example}

\pnum
If a structured binding declaration appears as a \grammarterm{condition},
the decision variable\iref{stmt.pre} of the condition is \exposid{e}.

\pnum
If the \grammarterm{initializer} refers to
one of the names introduced by the structured binding declaration,
the program is ill-formed.

\pnum
\tcode{E} shall not be an array type of unknown bound.
If \tcode{E} is any other array type with element type \tcode{T},
the structured binding size of \tcode{E} is equal to the
number of elements of \tcode{E}.
Each $\textrm{SB}_i$ is the name of an
lvalue that refers to the element $i$ of the array and whose type
is \tcode{T}; the referenced type is \tcode{T}.
\begin{note}
The top-level cv-qualifiers of \tcode{T} are \cv.
\end{note}
\begin{example}
\begin{codeblock}
auto f() -> int(&)[2];
auto [ x, y ] = f();            // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value
auto& [ xr, yr ] = f();         // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value

auto g() -> int(&)[4];

template<size_t N>
void h(int (&arr)[N]) {
  auto [a, ...b, c] = arr;  // \tcode{a} names the first element of the array, \tcode{b} is a pack referring to the second and
                            // third elements, and \tcode{c} names the fourth element
  auto& [...e] = arr;       // \tcode{e} is a pack referring to the four elements of the array
}

void call_h() {
  h(g());
}
\end{codeblock}
\end{example}

\pnum
Otherwise, if
the \grammarterm{qualified-id} \tcode{std::tuple_size<E>}
names a complete class type with a member named \tcode{value},
the expression \tcode{std::tuple_size<E>::value}
shall be a well-formed integral constant expression
whose value is non-negative;
the structured binding size of \tcode{E} is equal to that value.
Let \tcode{i} be an index prvalue of type \tcode{std::size_t}
corresponding to $\textrm{SB}_i$.
If a search for the name \tcode{get}
in the scope of \tcode{E}\iref{class.member.lookup}
finds at least one declaration
that is a function template whose first template parameter
is a constant template parameter,
the initializer is
\tcode{\exposidnc{e}.get<i>()}. Otherwise, the initializer is \tcode{get<i>(\exposid{e})},
where \tcode{get} undergoes argument-dependent lookup\iref{basic.lookup.argdep}.
In either case, \tcode{get<i>} is interpreted as a \grammarterm{template-id}.
\begin{note}
Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed.
\end{note}
In either case, \exposid{e} is an lvalue if the type of the entity \exposid{e}
is an lvalue reference and an xvalue otherwise.
Given the type $\tcode{T}_i$ designated by
\tcode{std::tuple_element<i, E>::type} and
the type $\tcode{U}_i$ defined
as $\tcode{T}_i$ if the initializer is a prvalue,
as ``lvalue reference to $\tcode{T}_i$'' if the initializer is an lvalue, or
as ``rvalue reference to $\tcode{T}_i$'' otherwise,
variables are introduced with unique names $\tcode{r}_i$ as follows:

\begin{ncbnf}
\placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;}
\end{ncbnf}

Each $\textrm{SB}_i$ is the name of an lvalue of type $\tcode{T}_i$
that refers to the object bound to $\tcode{r}_i$;
the referenced type is $\tcode{T}_i$.
The initialization of \exposid{e} and
any conversion of \exposid{e} considered as a decision variable\iref{stmt.pre}
is
sequenced before the initialization of any $\tcode{r}_i$.
The initialization of each $\tcode{r}_i$ is
sequenced before the initialization of any $\tcode{r}_j$ where $i < j$.

\pnum
Otherwise,
all of \tcode{E}'s non-static data members
shall be direct members of \tcode{E} or
of the same base class of \tcode{E},
well-formed when named as \tcode{\exposidnc{e}.\placeholder{name}}
in the context of the structured binding,
\tcode{E} shall not have an anonymous union member, and
the structured binding size of \tcode{E} is
equal to the number of non-static data members of \tcode{E}.
Designating the non-static data members of \tcode{E} as
$\tcode{m}_0$, $\tcode{m}_1$, $\tcode{m}_2, \dotsc$
(in declaration order),
each $\textrm{SB}_i$ is the
name of an lvalue that refers to the member \tcode{m}$_i$ of \exposid{e} and
whose type is
that of \tcode{\exposidnc{e}.$\tcode{m}_i$}\iref{expr.ref};
the referenced type is
the declared type of $\tcode{m}_i$ if that type is a reference type, or
the type of \tcode{\exposidnc{e}.$\tcode{m}_i$} otherwise.
The lvalue is a
bit-field if that member is a bit-field.
\begin{example}
\begin{codeblock}
struct S { mutable int x1 : 2; volatile double y1; };
S f();
const auto [ x, y ] = f();
\end{codeblock}
The type of the \grammarterm{id-expression} \tcode{x} is ``\tcode{int}'',
the type of the \grammarterm{id-expression} \tcode{y} is ``\tcode{const volatile double}''.
\end{example}

\rSec1[enum]{Enumerations}%

\rSec2[dcl.enum]{Enumeration declarations}%
\indextext{enumeration}%
\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}%
\indextext{\idxcode{enum}!type of}

\pnum
An enumeration is a distinct type\iref{basic.compound} with named
constants. Its name becomes an \grammarterm{enum-name} within its scope.

\begin{bnf}
\nontermdef{enum-name}\br
    identifier
\end{bnf}

\begin{bnf}
\nontermdef{enum-specifier}\br
    enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br
    enum-head \terminal{\{} enumerator-list \terminal{,} \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{enum-head}\br
    enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base}
\end{bnf}

\begin{bnf}
\nontermdef{enum-head-name}\br
    \opt{nested-name-specifier} identifier
\end{bnf}

\begin{bnf}
\nontermdef{opaque-enum-declaration}\br
    enum-key \opt{attribute-specifier-seq} enum-head-name \opt{enum-base} \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{enum-key}\br
    \keyword{enum}\br
    \keyword{enum} \keyword{class}\br
    \keyword{enum} \keyword{struct}
\end{bnf}

\begin{bnf}
\nontermdef{enum-base}\br
    \terminal{:} type-specifier-seq
\end{bnf}

\begin{bnf}
\nontermdef{enumerator-list}\br
    enumerator-definition\br
    enumerator-list \terminal{,} enumerator-definition
\end{bnf}

\begin{bnf}
\nontermdef{enumerator-definition}\br
    enumerator\br
    enumerator \terminal{=} constant-expression
\end{bnf}

\begin{bnf}
\nontermdef{enumerator}\br
    identifier \opt{attribute-specifier-seq}
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and
the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes
in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the
enumeration whenever it is named.
A \tcode{:} following
``\keyword{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}''
within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration}
is parsed as part of an \grammarterm{enum-base}.
\begin{note}
This resolves a potential ambiguity between the declaration of an enumeration
with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration
type.
\begin{example}
\begin{codeblock}
struct S {
  enum E : int {};
  enum E : int {};              // error: redeclaration of enumeration
};
\end{codeblock}

\end{example}
\end{note}
The \grammarterm{identifier} in an \grammarterm{enum-head-name}
is not looked up and is introduced by
the \grammarterm{enum-specifier} or \grammarterm{opaque-enum-declaration}.
If the \grammarterm{enum-head-name} of an \grammarterm{opaque-enum-declaration} contains
a \grammarterm{nested-name-specifier},
the declaration shall be an explicit specialization\iref{temp.expl.spec}.

\pnum
\indextext{constant!enumeration}%
The enumeration type declared with an \grammarterm{enum-key}
of only \keyword{enum} is an \defnadj{unscoped}{enumeration},
and its \grammarterm{enumerator}{s} are \defnx{unscoped enumerators}{enumerator!unscoped}.
The \grammarterm{enum-key}{s} \tcode{enum class} and
\tcode{enum struct} are semantically equivalent; an enumeration
type declared with one of these is a \defnadj{scoped}{enumeration},
and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}.
The optional \grammarterm{enum-head-name} shall not be omitted in the declaration of a scoped enumeration.
The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base}
shall name an integral type; any cv-qualification is ignored.
An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall
not omit the \grammarterm{enum-base}.
The identifiers in an \grammarterm{enumerator-list} are declared as
constants, and can appear wherever constants are required.
The same identifier shall not appear as
the name of multiple enumerators in an \grammarterm{enumerator-list}.
\indextext{enumerator!value of}%
An \grammarterm{enumerator-definition} with \tcode{=} gives the associated
\grammarterm{enumerator} the value indicated by the
\grammarterm{constant-expression}.
An \grammarterm{enumerator-definition} without \tcode{=} gives the associated
\grammarterm{enumerator} the value zero
if it is the first \grammarterm{enumerator-definition},
and the value of the previous \grammarterm{enumerator}
increased by one otherwise.
\begin{example}
\begin{codeblock}
enum { a, b, c=0 };
enum { d, e, f=e+2 };
\end{codeblock}
defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and
\tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}.
\end{example}
The optional \grammarterm{attribute-specifier-seq} in an
\grammarterm{enumerator} appertains to that enumerator.

\pnum
An \grammarterm{opaque-enum-declaration} is either a redeclaration
of an enumeration in the current scope or a declaration of a new enumeration.
\begin{note}
An enumeration declared by an
\grammarterm{opaque-enum-declaration} has a fixed underlying type and is a
complete type. The list of enumerators can be provided in a later redeclaration
with an \grammarterm{enum-specifier}.
\end{note}
A scoped enumeration
shall not be later redeclared as unscoped or with a different underlying type.
An unscoped enumeration shall not be later redeclared as scoped and each
redeclaration shall include an \grammarterm{enum-base} specifying the same
underlying type as in the original declaration.

\pnum
If an \grammarterm{enum-head-name} contains a
\grammarterm{nested-name-specifier},
the enclosing \grammarterm{enum-specifier}
or \grammarterm{opaque-enum-declaration} $D$
shall not inhabit a class scope and
shall correspond to one or more declarations nominable
in the class, class template, or namespace
to which the \grammarterm{nested-name-specifier} refers\iref{basic.scope.scope}.
All those declarations shall have the same target scope;
the target scope of $D$ is that scope.

\pnum
\indextext{\idxcode{enum}!type of}%
\indextext{\idxcode{enum}!underlying type|see{type, underlying}}%
Each enumeration defines a type that is different from all other types.
Each enumeration also has an \defnx{underlying type}{type!underlying!enumeration}.
The underlying type can be explicitly specified using an \grammarterm{enum-base}.
For a scoped enumeration type, the underlying type is \tcode{int} if it is not
explicitly specified. In both of these cases, the underlying type is said to be
\defnx{fixed}{type!underlying!fixed}.
Following the closing brace of an \grammarterm{enum-specifier}, each
enumerator has the type of its enumeration.
If the underlying type is fixed, the type of each enumerator
prior to the closing brace is the underlying
type
and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition}
shall be a converted constant expression of the underlying
type\iref{expr.const.const}.
If the underlying
type is not fixed,
the type of each enumerator prior to the closing brace is determined as
follows:

\begin{itemize}
\item If an
initializer is specified for an enumerator, the
\grammarterm{constant-expression} shall be an integral constant
expression\iref{expr.const.const}. If the expression has
unscoped enumeration type, the enumerator has the underlying type of that
enumeration type, otherwise it has the same type as the expression.

\item If no initializer is specified for the
first enumerator, its type is an unspecified signed integral type.

\item  Otherwise
the type of the enumerator is the same as that of the
preceding enumerator unless the incremented value is not representable
in that type, in which case the type is an unspecified integral type
sufficient to contain the incremented value. If no such type exists, the program
is ill-formed.
\end{itemize}

\pnum
An enumeration whose underlying type is fixed is an incomplete type
until immediately after its
\grammarterm{enum-base} (if any), at which point it becomes a complete type.
An enumeration whose underlying type is not fixed is an incomplete type
until the closing \tcode{\}} of its
\grammarterm{enum-specifier}, at which point it becomes a complete type.

\pnum
For an enumeration whose underlying type is not fixed,
the underlying type
is an
integral type that can represent all the enumerator values defined in
the enumeration. If no integral type can represent all the enumerator
values, the enumeration is ill-formed. It is \impldef{underlying type for enumeration}
which integral type is used as the underlying type
except that the underlying type shall not be larger than \tcode{int}
unless the value of an enumerator cannot fit in an \tcode{int} or
\tcode{unsigned int}. If the \grammarterm{enumerator-list} is empty, the
underlying type is as if the enumeration had a single enumerator with
value 0.

\pnum
\indextext{signed integer representation!two's complement}%
For an enumeration whose underlying type is fixed, the values of
the enumeration are the values of the underlying type. Otherwise,
the values of the enumeration are the values representable by
a hypothetical integer type with minimal width $M$
such that all enumerators can be represented.
The width of the smallest bit-field large enough to hold all the values of the
enumeration type is $M$.
It is possible to define an enumeration that has values not defined by
any of its enumerators. If the \grammarterm{enumerator-list} is empty, the
values of the enumeration are as if the enumeration had a single enumerator with
value 0.
\begin{footnote}
This set of values is used to define promotion and
conversion semantics for the enumeration type. It does not preclude an
expression of enumeration type from having a value that falls outside
this range.
\end{footnote}

\pnum
An enumeration has
the same size,
value representation, and
alignment requirements\iref{basic.align}
as its underlying type.
Furthermore, each value of an enumeration has the same representation
as the corresponding value of the underlying type.

\pnum
Two enumeration types are \defnx{layout-compatible enumerations}{layout-compatible!enumeration}
if they have the same underlying type.

\pnum
The value of an enumerator or an object of an unscoped enumeration type is
converted to an integer by integral promotion\iref{conv.prom}.
\begin{example}
\begin{codeblock}
enum color { red, yellow, green=20, blue };
color col = red;
color* cp = &col;
if (*cp == blue)                // ...
\end{codeblock}
makes \tcode{color} a type describing various colors, and then declares
\tcode{col} as an object of that type, and \tcode{cp} as a pointer to an
object of that type. The possible values of an object of type
\tcode{color} are \tcode{red}, \tcode{yellow}, \tcode{green},
\tcode{blue}; these values can be converted to the integral values
\tcode{0}, \tcode{1}, \tcode{20}, and \tcode{21}. Since enumerations are
distinct types, objects of type \tcode{color} can be assigned only
values of type \tcode{color}.
\begin{codeblock}
color c = 1;                    // error: type mismatch, no conversion from \tcode{int} to \tcode{color}
int i = yellow;                 // OK, \tcode{yellow} converted to integral value \tcode{1}, integral promotion
\end{codeblock}
Note that this implicit \keyword{enum} to \tcode{int}
conversion is not provided for a scoped enumeration:
\begin{codeblock}
enum class Col { red, yellow, green };
int x = Col::red;               // error: no \tcode{Col} to \tcode{int} conversion
Col y = Col::red;
if (y) { }                      // error: no \tcode{Col} to \tcode{bool} conversion
\end{codeblock}
\end{example}

\pnum
\indextext{class!scope of enumerator}%
The name of each unscoped enumerator is also bound
in the scope that immediately contains the \grammarterm{enum-specifier}.
An unnamed enumeration
that does not have a typedef name for linkage purposes\iref{dcl.typedef} and
that has a first enumerator
is denoted, for linkage purposes\iref{basic.link},
by its underlying type and its first enumerator;
such an enumeration is said to have
an enumerator as a name for linkage purposes.
\begin{note}
Each unnamed enumeration with no enumerators is a distinct type.
\end{note}
\begin{example}
\begin{codeblock}
enum direction { left='l', right='r' };

void g() {
  direction d;                  // OK
  d = left;                     // OK
  d = direction::right;         // OK
}

enum class altitude { high='h', low='l' };

void h() {
  altitude a;                   // OK
  a = high;                     // error: \tcode{high} not in scope
  a = altitude::low;            // OK
}
\end{codeblock}
\end{example}

\rSec2[enum.udecl]{The \tcode{using enum} declaration}%
\indextext{enumeration!using declaration}%

\begin{bnf}
\nontermdef{using-enum-declaration}\br
    \keyword{using} \keyword{enum} using-enum-declarator \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{using-enum-declarator}\br
    \opt{nested-name-specifier} identifier\br
    \opt{nested-name-specifier} simple-template-id\br
    splice-type-specifier
\end{bnf}

\pnum
A \grammarterm{using-enum-declarator} of
the form \grammarterm{splice-type-specifier}
designates the same type designated by the \grammarterm{splice-type-specifier}.
Any other \grammarterm{using-enum-declarator}
names the set of declarations found by
type-only lookup\iref{basic.lookup.general}
for the \grammarterm{using-enum-declarator}\iref{basic.lookup.unqual,basic.lookup.qual}.
The \grammarterm{using-enum-declarator}
shall designate a non-dependent type
with a reachable \grammarterm{enum-specifier}.
\begin{example}
\begin{codeblock}
enum E { x };
void f() {
  int E;
  using enum E;                 // OK
}
using F = E;
using enum F;                   // OK
template<class T> using EE = T;
void g() {
  using enum EE<E>;             // OK
}
\end{codeblock}
\end{example}

\pnum
A \grammarterm{using-enum-declaration}
is equivalent to a \grammarterm{using-declaration} for each enumerator.

\pnum
\begin{note}
A \grammarterm{using-enum-declaration} in class scope
makes the enumerators of the named enumeration available via member lookup.
\begin{example}
\begin{codeblock}
enum class fruit { orange, apple };
struct S {
  using enum fruit;             // OK, introduces \tcode{orange} and \tcode{apple} into \tcode{S}
};
void f() {
  S s;
  s.orange;                     // OK, names \tcode{fruit::orange}
  S::orange;                    // OK, names \tcode{fruit::orange}
}
\end{codeblock}
\end{example}
\end{note}

\pnum
\begin{note}
Two \grammarterm{using-enum-declaration}s
that introduce two enumerators of the same name conflict.
\begin{example}
\begin{codeblock}
enum class fruit { orange, apple };
enum class color { red, orange };
void f() {
  using enum fruit;             // OK
  using enum color;             // error: \tcode{color::orange} and \tcode{fruit::orange} conflict
}
\end{codeblock}
\end{example}
\end{note}

\rSec1[basic.namespace]{Namespaces}%

\rSec2[basic.namespace.general]{General}%
\indextext{namespaces|(}

\pnum
A namespace is an optionally-named entity
whose scope can contain declarations of any kind of entity.
The name of a
namespace can be used to access entities that belong to that namespace;
that is, the \defnx{members}{member!namespace} of the namespace.
Unlike other entities,
the definition of a namespace can be split over several parts of one or
more translation units and modules.

\pnum
\begin{note}
A \grammarterm{namespace-definition} is exported
if it contains any
\grammarterm{export-declaration}{s}\iref{module.interface}.
A namespace is never attached to a named module
and never has a name with module linkage.
\end{note}
\begin{example}
\begin{codeblock}
export module M;
namespace N1 {}                 // \tcode{N1} is not exported
export namespace N2 {}          // \tcode{N2} is exported
namespace N3 { export int n; }  // \tcode{N3} is exported
\end{codeblock}
\end{example}

\pnum
There is a \defnadj{global}{namespace} with no declaration;
see~\ref{basic.scope.namespace}.
The global namespace belongs to the global scope;
it is not an unnamed namespace\iref{namespace.unnamed}.
\begin{note}
Lacking a declaration, it cannot be found by name lookup.
\end{note}

\rSec2[namespace.def]{Namespace definition}%

\rSec3[namespace.def.general]{General}%
\indextext{definition!namespace}%
\indextext{namespace!definition}

\begin{bnf}
\nontermdef{namespace-name}\br
        identifier\br
        namespace-alias
\end{bnf}

\begin{bnf}
\nontermdef{namespace-definition}\br
        named-namespace-definition\br
        unnamed-namespace-definition\br
        nested-namespace-definition
\end{bnf}

\begin{bnf}
\nontermdef{named-namespace-definition}\br
        \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{unnamed-namespace-definition}\br
        \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{nested-namespace-definition}\br
        \keyword{namespace} enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \terminal{\{} namespace-body \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{enclosing-namespace-specifier}\br
        identifier\br
        enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier
\end{bnf}

\begin{bnf}
\nontermdef{namespace-body}\br
        \opt{declaration-seq}
\end{bnf}

\pnum
Every \grammarterm{namespace-definition} shall inhabit a namespace scope\iref{basic.scope.namespace}.

\pnum
In a \grammarterm{named-namespace-definition} $D$,
the \grammarterm{identifier} is the name of the namespace.
The \grammarterm{identifier} is looked up
by searching for it in the scopes of the namespace $A$
in which $D$ appears
and of every element of the inline namespace set of $A$.
If the lookup finds a \grammarterm{namespace-definition} for a namespace $N$,
\indextext{extend|see{namespace, extend}}%
$D$ \defnx{extends}{namespace!extend} $N$,
and the target scope of $D$ is the scope to which $N$ belongs.
If the lookup finds nothing, the \grammarterm{identifier} is introduced
as a \grammarterm{namespace-name} into $A$.

\pnum
Because a \grammarterm{namespace-definition} contains
\grammarterm{declaration}{s} in its \grammarterm{namespace-body} and a
\grammarterm{namespace-definition} is itself a \grammarterm{declaration}, it
follows that \grammarterm{namespace-definition}{s} can be nested.
\begin{example}
\begin{codeblock}
namespace Outer {
  int i;
  namespace Inner {
    void f() { i++; }           // \tcode{Outer::i}
    int i;
    void g() { i++; }           // \tcode{Inner::i}
  }
}
\end{codeblock}
\end{example}

\pnum
If the optional initial \keyword{inline} keyword appears in a
\grammarterm{namespace-definition} for a particular namespace, that namespace is
declared to be an \defnadj{inline}{namespace}. The \keyword{inline} keyword may be
used on a \grammarterm{namespace-definition} that extends a namespace
only if it was previously used on the \grammarterm{namespace-definition}
that initially declared the \grammarterm{namespace-name} for that namespace.

\pnum
The optional \grammarterm{attribute-specifier-seq}
in a \grammarterm{named-namespace-definition}
appertains to the namespace being defined or extended.

\pnum
Members of an inline namespace can be used in most respects as though they were members
of the innermost enclosing namespace. Specifically, the inline namespace and its enclosing
namespace are both added to the set of associated namespaces used in
argument-dependent lookup\iref{basic.lookup.argdep} whenever one of them is,
and a \grammarterm{using-directive}\iref{namespace.udir} that names the inline
namespace is implicitly inserted into the enclosing namespace as for an unnamed
namespace\iref{namespace.unnamed}. Furthermore, each
member of the inline namespace can subsequently be partially
specialized\iref{temp.spec.partial}, explicitly
instantiated\iref{temp.explicit}, or explicitly specialized\iref{temp.expl.spec} as
though it were a member of the enclosing namespace. Finally, looking up a name in the
enclosing namespace via explicit qualification\iref{namespace.qual} will include
members of the inline namespace even if
there are declarations of that name in the enclosing namespace.

\pnum
These properties are transitive: if a namespace \tcode{N} contains an inline namespace
\tcode{M}, which in turn contains an inline namespace \tcode{O}, then the members of
\tcode{O} can be used as though they were members of \tcode{M} or \tcode{N}.
The \defn{inline namespace set} of \tcode{N} is the transitive closure of all
inline namespaces in \tcode{N}.

\pnum
A \grammarterm{nested-namespace-definition} with an
\grammarterm{enclosing-namespace-specifier} \tcode{E},
\grammarterm{identifier} \tcode{I} and
\grammarterm{namespace-body} \tcode{B}
is equivalent to
\begin{codeblock}
namespace E { @\opt{inline}@ namespace I { B } }
\end{codeblock}
where the optional \keyword{inline} is present if and only if
the \grammarterm{identifier} \tcode{I} is preceded by \keyword{inline}.
\begin{example}
\begin{codeblock}
namespace A::inline B::C {
  int i;
}
\end{codeblock}
The above has the same effect as:
\begin{codeblock}
namespace A {
  inline namespace B {
    namespace C {
      int i;
    }
  }
}
\end{codeblock}
\end{example}

\rSec3[namespace.unnamed]{Unnamed namespaces}%
\indextext{namespace!unnamed}

\pnum
An \grammarterm{unnamed-namespace-definition} behaves as if it were
replaced by
\begin{ncsimplebnf}
\opt{\keyword{inline}} \keyword{namespace} \exposid{unique} \terminal{\{} \terminal{/* empty body */} \terminal{\}}\br
\keyword{using} \keyword{namespace} \exposid{unique} \terminal{;}\br
\keyword{namespace} \exposid{unique} \terminal{\{} namespace-body \terminal{\}}
\end{ncsimplebnf}
where
\keyword{inline} appears if and only if it appears in the
\grammarterm{unnamed-namespace-definition}
and all occurrences of \exposid{unique} in a translation unit are replaced by
the same identifier, and this identifier differs from all other
identifiers in the program.
The optional \grammarterm{attribute-specifier-seq}
in the \grammarterm{unnamed-namespace-definition}
appertains to \exposid{unique}.
\begin{example}
\begin{codeblock}
namespace { int i; }            // \tcode{\exposid{unique}::i}
void f() { i++; }               // \tcode{\exposid{unique}::i++}

namespace A {
  namespace {
    int i;                      // \tcode{A::\exposid{unique}::i}
    int j;                      // \tcode{A::\exposid{unique}::j}
  }
  void g() { i++; }             // \tcode{A::\exposid{unique}::i++}
}

using namespace A;
void h() {
  i++;                          // error: \tcode{\exposid{unique}::i} or \tcode{A::\exposid{unique}::i}
  A::i++;                       // \tcode{A::\exposid{unique}::i}
  j++;                          // \tcode{A::\exposid{unique}::j}
}
\end{codeblock}
\end{example}

\rSec2[namespace.alias]{Namespace alias}%
\indextext{namespace!alias}%
\indextext{alias!namespace}%
\indextext{synonym}

\pnum
A \grammarterm{namespace-alias-definition} declares a \defnadj{namespace}{alias}
according to the following grammar:

\begin{bnf}
\nontermdef{namespace-alias}\br
        identifier
\end{bnf}

\begin{bnf}
\nontermdef{namespace-alias-definition}\br
        \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;}\br
        \keyword{namespace} identifier \terminal{=} splice-specifier \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{qualified-namespace-specifier}\br
    \opt{nested-name-specifier} namespace-name
\end{bnf}

\pnum
The \grammarterm{splice-specifier} (if any)
shall designate a namespace that is not the global namespace.

\pnum
The \grammarterm{identifier} in a \grammarterm{namespace-alias-definition}
becomes a \grammarterm{namespace-alias}.

\pnum
The underlying entity\iref{basic.pre} of the namespace alias is
the namespace either
denoted by the \grammarterm{qualified-namespace-specifier} or
designated by the \grammarterm{splice-specifier}.
\begin{note}
When looking up a \grammarterm{namespace-name} in a
\grammarterm{namespace-alias-definition}, only namespace names are
considered, see~\ref{basic.lookup.udir}.
\end{note}

\rSec2[namespace.udir]{Using namespace directive}%
\indextext{using-directive|(}

\begin{bnf}
\nontermdef{using-directive}\br
    \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} \opt{nested-name-specifier} namespace-name \terminal{;}\br
    \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} splice-specifier \terminal{;}
\end{bnf}

\pnum
The \grammarterm{splice-specifier} (if any) shall designate a namespace
that is not the global namespace.
The \grammarterm{nested-name-specifier},
\grammarterm{namespace-name}, and
\grammarterm{splice-specifier}
shall not be dependent.

\pnum
A \grammarterm{using-directive} shall not appear in class scope, but may
appear in namespace scope or in block scope.
\begin{note}
When looking up a \grammarterm{namespace-name} in a
\grammarterm{using-directive}, only namespace names are considered,
see~\ref{basic.lookup.udir}.
\end{note}
The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{using-directive}.

\pnum
\begin{note}
A \grammarterm{using-directive} makes the names in the designated
namespace usable in the scope in which the
\grammarterm{using-directive} appears after
the \grammarterm{using-directive}\iref{basic.lookup.unqual,namespace.qual}.
During unqualified name lookup, the names
appear as if they were declared in the nearest enclosing namespace which
contains both the \grammarterm{using-directive} and the designated
namespace.
\end{note}

\pnum
\begin{note}
A \grammarterm{using-directive} does not introduce any names.
\end{note}
\begin{example}
\begin{codeblock}
namespace A {
  int i;
  namespace B {
    namespace C {
      int i;
    }
    using namespace A::B::C;
    void f1() {
      i = 5;        // OK, \tcode{C::i} visible in \tcode{B} and hides \tcode{A::i}
    }
  }
  namespace D {
    using namespace B;
    using namespace C;
    void f2() {
      i = 5;        // ambiguous, \tcode{B::C::i} or \tcode{A::i}?
    }
  }
  void f3() {
    i = 5;          // uses \tcode{A::i}
  }
}
void f4() {
  i = 5;            // error: neither \tcode{i} is visible
}
\end{codeblock}
\end{example}

\pnum
\begin{note}
A \grammarterm{using-directive} is transitive: if a scope contains a
\grammarterm{using-directive} that designates a namespace that itself
contains \grammarterm{using-directive}{s}, the namespaces designated by those
\grammarterm{using-directive}{s} are also eligible to be considered.
\end{note}
\begin{example}
\begin{codeblock}
namespace M {
  int i;
}

namespace N {
  int i;
  using namespace M;
}

void f() {
  using namespace N;
  i = 7;            // error: both \tcode{M::i} and \tcode{N::i} are visible
}
\end{codeblock}

For another example,
\begin{codeblock}
namespace A {
  int i;
}
namespace B {
  int i;
  int j;
  namespace C {
    namespace D {
      using namespace A;
      int j;
      int k;
      int a = i;    // \tcode{B::i} hides \tcode{A::i}
    }
    using namespace D;
    int k = 89;     // no problem yet
    int l = k;      // ambiguous: \tcode{C::k} or \tcode{D::k}
    int m = i;      // \tcode{B::i} hides \tcode{A::i}
    int n = j;      // \tcode{D::j} hides \tcode{B::j}
  }
}
\end{codeblock}
\end{example}


\pnum
\begin{note}
Declarations in a namespace
that appear after a \grammarterm{using-directive} for that namespace
can be found through that \grammarterm{using-directive} after they appear.
\end{note}

\pnum
\begin{note}
If name lookup finds a declaration for a name in two different
namespaces, and the declarations do not declare the same entity and do
not declare functions or function templates, the use of the name is ill-formed\iref{basic.lookup}.
In particular, the name of a variable, function or enumerator does not
hide the name of a class or enumeration declared in a different
namespace. For example,

\begin{codeblock}
namespace A {
  class X { };
  extern "C"   int g();
  extern "C++" int h();
}
namespace B {
  void X(int);
  extern "C"   int g();
  extern "C++" int h(int);
}
using namespace A;
using namespace B;

void f() {
  X(1);             // error: name \tcode{X} found in two namespaces
  g();              // OK, name \tcode{g} refers to the same entity
  h();              // OK, overload resolution selects \tcode{A::h}
}
\end{codeblock}
\end{note}

\pnum
\indextext{overloading!using directive and}%
\begin{note}
The order in which namespaces are considered and the
relationships among the namespaces implied by the
\grammarterm{using-directive}{s} do not affect overload resolution.
Neither is any function excluded because another has the same
signature, even if one is in a namespace reachable through
\grammarterm{using-directive}{s} in the namespace of the other.
\begin{footnote}
During
name lookup in a class hierarchy, some ambiguities can be
resolved by considering whether one member hides the other along some
paths\iref{class.member.lookup}. There is no such disambiguation when
considering the set of names found as a result of following
\grammarterm{using-directive}{s}.
\end{footnote}
\end{note}
\begin{example}
\begin{codeblock}
namespace D {
  int d1;
  void f(char);
}
using namespace D;

int d1;             // OK, no conflict with \tcode{D::d1}

namespace E {
  int e;
  void f(int);
}

namespace D {       // namespace extension
  int d2;
  using namespace E;
  void f(int);
}

void f() {
  d1++;             // error: ambiguous \tcode{::d1} or \tcode{D::d1}?
  ::d1++;           // OK
  D::d1++;          // OK
  d2++;             // OK, \tcode{D::d2}
  e++;              // OK, \tcode{E::e}
  f(1);             // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}?
  f('a');           // OK, \tcode{D::f(char)}
}
\end{codeblock}
\end{example}
\indextext{using-directive|)}%
\indextext{namespaces|)}

\rSec1[namespace.udecl]{The \tcode{using} declaration}%
\indextext{using-declaration|(}

\begin{bnf}
\nontermdef{using-declaration}\br
    \keyword{using} using-declarator-list \terminal{;}
\end{bnf}

\begin{bnf}
\nontermdef{using-declarator-list}\br
    using-declarator \opt{\terminal{...}}\br
    using-declarator-list \terminal{,} using-declarator \opt{\terminal{...}}
\end{bnf}

\begin{bnf}
\nontermdef{using-declarator}\br
    \opt{\keyword{typename}} nested-name-specifier unqualified-id
\end{bnf}

\pnum
\indextext{component name}%
The component names of a \grammarterm{using-declarator} are those
of its \grammarterm{nested-name-specifier} and \grammarterm{unqualified-id}.
Each \grammarterm{using-declarator} in a \grammarterm{using-declaration}
\begin{footnote}
A \grammarterm{using-declaration} with more than one
\grammarterm{using-declarator} is equivalent to a corresponding sequence
of \grammarterm{using-declaration}{s} with
one \grammarterm{using-declarator} each.
\end{footnote}
names the set of declarations found by lookup\iref{basic.lookup.qual}
for the \grammarterm{using-declarator},
except that class and enumeration declarations that would be discarded
are merely ignored when checking for ambiguity\iref{basic.lookup},
conversion function templates with a dependent return type are ignored, and
certain functions are hidden as described below.
If the terminal name of the \grammarterm{using-declarator}
is dependent\iref{temp.dep.type},
the \grammarterm{using-declarator} is considered to name a constructor
if and only if the \grammarterm{nested-name-specifier} has a terminal name
that is the same as the \grammarterm{unqualified-id}.
If the lookup in any instantiation finds
that a \grammarterm{using-declarator}
that is not considered to name a constructor does do so, or
that a \grammarterm{using-declarator}
that is considered to name a constructor does not,
the program is ill-formed.

\pnum
\indextext{inheritance!\idxgram{using-declaration} and}%
If the \grammarterm{using-declarator} names a constructor,
it declares that the class \defnx{inherits}{constructor!inherited} the named set of constructor declarations
from the nominated base class.
\begin{note}
Otherwise,
the \grammarterm{unqualified-id} in the \grammarterm{using-declarator}
is bound to the \grammarterm{using-declarator},
which is replaced during name lookup
with the declarations it names\iref{basic.lookup}.
If such a declaration is of an enumeration,
the names of its enumerators are not bound.
For the keyword \keyword{typename}, see \ref{temp.res}.
\end{note}

\pnum
In a \grammarterm{using-declaration} used as a
\grammarterm{member-declaration},
each \grammarterm{using-declarator}
shall either name an enumerator
or have a \grammarterm{nested-name-specifier}
naming a base class of the current class\iref{expr.prim.this}.
\begin{example}
\begin{codeblock}
enum class button { up, down };
struct S {
  using button::up;
  button b = up;                // OK
};
\end{codeblock}
\end{example}
If a
\grammarterm{using-declarator} names a constructor,
its \grammarterm{nested-name-specifier} shall name
a direct base class of the current class.
If the immediate (class) scope is associated with a class template,
it shall derive from the specified base class or
have at least one dependent base class.
\begin{example}
\begin{codeblock}
struct B {
  void f(char);
  enum E { e };
  union { int x; };
};

struct C {
  int f();
};

struct D : B {
  using B::f;                   // OK, \tcode{B} is a base of \tcode{D}
  using B::e;                   // OK, \tcode{e} is an enumerator of base \tcode{B}
  using B::x;                   // OK, \tcode{x} is a union member of base \tcode{B}
  using C::f;                   // error: \tcode{C} isn't a base of \tcode{D}
  void f(int) { f('c'); }       // calls \tcode{B::f(char)}
  void g(int) { g('c'); }       // recursively calls \tcode{D::g(int)}
};
template <typename... bases>
struct X : bases... {
  using bases::f...;
};
X<B, C> x;                      // OK, \tcode{B::f} and \tcode{C::f} named
\end{codeblock}
\end{example}

\pnum
\begin{note}
Since destructors do not have names, a
\grammarterm{using-declaration} cannot refer to a
destructor for a base class.
\end{note}
\begin{note}
A \grammarterm{using-declarator} that
names a member function of a base class
does not suppress the implicit declaration of a special member function
in the derived class,
even if their signatures are the
same\iref{class.default.ctor, class.copy.ctor, class.copy.assign}.
\end{note}

\pnum
A \grammarterm{using-declaration} shall not name a \grammarterm{template-id}.
\begin{example}
\begin{codeblock}
struct A {
  template <class T> void f(T);
  template <class T> struct X { };
};
struct B : A {
  using A::f<double>;           // error
  using A::X<int>;              // error
};
\end{codeblock}
\end{example}

\pnum
A \grammarterm{using-declaration} shall not name a namespace.

\pnum
A \grammarterm{using-declaration} that names a class member
other than an enumerator
shall be a
\grammarterm{member-declaration}.
\begin{example}
\begin{codeblock}
struct X {
  int i;
  static int s;
};

void f() {
  using X::i;                   // error: \tcode{X::i} is a class member and this is not a member declaration.
  using X::s;                   // error: \tcode{X::s} is a class member and this is not a member declaration.
}
\end{codeblock}
\end{example}

\pnum
If a declaration is named by two \grammarterm{using-declarator}s
that inhabit the same class scope, the program is ill-formed.
\begin{example}
\begin{codeblock}
struct C {
  int i;
};

struct D1 : C { };
struct D2 : C { };

struct D3 : D1, D2 {
  using D1::i;                  // OK, equivalent to \tcode{using C::i}
  using D1::i;                  // error: duplicate
  using D2::i;                  // error: duplicate, also names \tcode{C::i}
};
\end{codeblock}
\end{example}

\pnum
\begin{note}
A \grammarterm{using-declarator}
whose \grammarterm{nested-name-specifier} names a namespace
does not name declarations added to the namespace after it. Thus, additional
overloads added after the \grammarterm{using-declaration} are ignored, but
default function arguments\iref{dcl.fct.default}, default template
arguments\iref{temp.param}, and
template specializations\iref{temp.spec.partial,temp.expl.spec} are considered.
\end{note}
\begin{example}
\begin{codeblock}
namespace A {
  void f(int);
}

using A::f;         // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)}.
namespace A {
  void f(char);
}

void foo() {
  f('a');           // calls \tcode{f(int)}, even though \tcode{f(char)} exists.
}

void bar() {
  using A::f;       // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)} and \tcode{A::f(char)}.
  f('a');           // calls \tcode{f(char)}
}
\end{codeblock}
\end{example}

\pnum
If a declaration named by a \grammarterm{using-declaration}
that inhabits the target scope of another declaration $B$
potentially conflicts with it\iref{basic.scope.scope}, and
either is reachable from the other, the program is ill-formed
unless $B$ is name-independent and
the \grammarterm{using-declaration} precedes $B$.
\begin{example}
\begin{codeblock}
int _;
void f() {
  int _;                // B
  _ = 0;
  using ::_;            // error: \grammarterm{using-declaration} does not precede B
}
\end{codeblock}
\end{example}
If two declarations named by \grammarterm{using-declaration}s
that inhabit the same scope potentially conflict,
either is reachable from the other, and
they do not both declare functions or function templates,
the program is ill-formed.
\begin{note}
Overload resolution possibly cannot distinguish
between conflicting function declarations.
\end{note}
\begin{example}
\begin{codeblock}
namespace A {
  int x;
  int f(int);
  int g;
  void h();
}

namespace B {
  int i;
  struct g { };
  struct x { };
  void f(int);
  void f(double);
  void g(char);                         // OK, hides \tcode{struct g}
}

void func() {
  int i;
  using B::i;                           // error: conflicts
  void f(char);
  using B::f;                           // OK, each \tcode{f} is a function
  using A::f;                           // OK, but interferes with \tcode{B::f(int)}
  f(1);                                 // error: ambiguous
  static_cast<int(*)(int)>(f)(1);       // OK, calls \tcode{A::f}
  f(3.5);                               // calls \tcode{B::f(double)}
  using B::g;
  g('a');                               // calls \tcode{B::g(char)}
  struct g g1;                          // \tcode{g1} has class type \tcode{B::g}
  using A::g;                           // error: conflicts with \tcode{B::g}
  void h();
  using A::h;                           // error: conflicts
  using B::x;
  using A::x;                           // OK, hides \tcode{struct B::x}
  using A::x;                           // OK, does not conflict with previous \tcode{using A::x}
  x = 99;                               // assigns to \tcode{A::x}
  struct x x1;                          // \tcode{x1} has class type \tcode{B::x}
}
\end{codeblock}
\end{example}

\pnum
\indextext{name hiding!using-declaration and}%
The set of declarations named by a \grammarterm{using-declarator}
that inhabits a class \tcode{C} does not include
member functions and member function templates of a base class that,
when considered as members of \tcode{C},
correspond to a declaration of a function or function template in \tcode{C}.
\begin{example}
\begin{codeblock}
struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
  void i();
  void j();
};

struct D : B {
  using B::f;
  void f(int);      // OK, \tcode{D::f(int)} overrides \tcode{B::f(int)};

  using B::g;
  void g(char);     // OK

  using B::h;
  void h(int);      // OK, \tcode{D::h(int)} hides \tcode{B::h(int)}

  using B::i;
  void i(this B &); // OK

  using B::j;
  void j(this D &); // OK, \tcode{D::j()} hides \tcode{B::j()}
};

void k(D* p)
{
  p->f(1);          // calls \tcode{D::f(int)}
  p->f('a');        // calls \tcode{B::f(char)}
  p->g(1);          // calls \tcode{B::g(int)}
  p->g('a');        // calls \tcode{D::g(char)}
  p->i();           // calls \tcode{B::i}, because \tcode{B::i} as a member of \tcode{D} is a better match than \tcode{D::i}
  p->j();           // calls \tcode{D::j}
}

struct B1 {
  B1(int);
};

struct B2 {
  B2(int);
};

struct D1 : B1, B2 {
  using B1::B1;
  using B2::B2;
};
D1 d1(0);           // error: ambiguous

struct D2 : B1, B2 {
  using B1::B1;
  using B2::B2;
  D2(int);          // OK, \tcode{D2::D2(int)} hides \tcode{B1::B1(int)} and \tcode{B2::B2(int)}
};
D2 d2(0);           // calls \tcode{D2::D2(int)}
\end{codeblock}
\end{example}

\pnum
\indextext{overloading!using-declaration and}%
\begin{note}
For the purpose of forming a set of candidates during overload resolution,
the functions
named by a \grammarterm{using-declaration} in a derived class
are treated as though they were direct members of the derived class. In
particular, the implicit object parameter is treated as if
it were a reference to the derived class rather than to the base class\iref{over.match.funcs}.
This has no effect on the type of the function, and in all other
respects the function remains part of the base class.
\end{note}

\pnum
Constructors that are named by a \grammarterm{using-declaration}
are treated as though they were constructors of the derived class
when looking up the constructors of the derived class\iref{class.qual}
or forming a set of overload candidates\iref{over.match.ctor,over.match.copy,over.match.list}.
\begin{note}
If such a constructor is selected to perform the initialization
of an object of class type, all subobjects other than the base class
from which the constructor originated
are implicitly initialized\iref{class.inhctor.init}.
A constructor of a derived class is sometimes preferred to a constructor of a base class
if they would otherwise be ambiguous\iref{over.match.best}.
\end{note}

\pnum
\indextext{access control!using-declaration and}%
In a \grammarterm{using-declarator} that does not name a constructor,
every declaration named shall be accessible.
In a \grammarterm{using-declarator} that names a constructor,
no access check is performed.

\pnum
\begin{note}
Because a \grammarterm{using-declarator} designates a base class member
(and not a member subobject or a member function of a base class
subobject), a \grammarterm{using-declarator} cannot be used to resolve
inherited member ambiguities.
\begin{example}
\begin{codeblock}
struct A { int x(); };
struct B : A { };
struct C : A {
  using A::x;
  int x(int);
};

struct D : B, C {
  using C::x;
  int x(double);
};
int f(D* d) {
  return d->x();    // error: overload resolution selects \tcode{A::x}, but \tcode{A} is an ambiguous base class
}
\end{codeblock}
\end{example}
\end{note}

\pnum
A \grammarterm{using-declaration} has the usual
accessibility for a \grammarterm{member-declaration}.
Base-class constructors considered because of a \grammarterm{using-declarator}
are accessible if they would be accessible
when used to construct an object of the base class;
the accessibility of the \grammarterm{using-declaration} is ignored.
\begin{example}
\begin{codeblock}
class A {
private:
    void f(char);
public:
    void f(int);
protected:
    void g();
};

class B : public A {
  using A::f;       // error: \tcode{A::f(char)} is inaccessible
public:
  using A::g;       // \tcode{B::g} is a public synonym for \tcode{A::g}
};
\end{codeblock}
\end{example}

\indextext{using-declaration|)}

\rSec1[dcl.asm]{The \tcode{asm} declaration}%
\indextext{declaration!\idxcode{asm}}%
\indextext{assembler}%
\indextext{\idxcode{asm}!implementation-defined}

\pnum
An \tcode{asm} declaration has the form
\begin{bnf}
\nontermdef{asm-declaration}\br
    \opt{attribute-specifier-seq} \keyword{asm} \terminal{(} balanced-token-seq \terminal{)} \terminal{;}
\end{bnf}

The \tcode{asm} declaration is conditionally-supported;
any restrictions on the \grammarterm{balanced-token-seq} and
its meaning are \impldef{meaning of \tcode{asm} declaration}.
The optional \grammarterm{attribute-specifier-seq} in
an \grammarterm{asm-declaration} appertains to the \tcode{asm} declaration.
\begin{note}
Typically it is used to pass information through the implementation to
an assembler.
\end{note}

\rSec1[dcl.link]{Linkage specifications}%
\indextext{specification!linkage|(}

\pnum
All functions and variables whose names have external linkage
and all function types
have a \defn{language linkage}.
\begin{note}
Some of the properties associated with an entity with language linkage
are specific to each implementation and are not described here. For
example, a particular language linkage might be associated with a
particular form of representing names of objects and functions with
external linkage, or with a particular calling convention, etc.
\end{note}
The default language linkage of all function types, functions, and
variables is \Cpp{} language linkage. Two function types with
different language linkages are distinct types even if they are
otherwise identical.

\pnum
Linkage\iref{basic.link} between \Cpp{} and  non-\Cpp{} code fragments can
be achieved using a \grammarterm{linkage-specification}:

\indextext{\idxgram{linkage-specification}}%
\indextext{specification!linkage!\idxcode{extern}}%
%
\begin{bnf}
\nontermdef{linkage-specification}\br
    \keyword{extern} unevaluated-string \terminal{\{} \opt{declaration-seq} \terminal{\}}\br
    \keyword{extern} unevaluated-string name-declaration
\end{bnf}

The \grammarterm{unevaluated-string} indicates the required language linkage.
\begin{note}
Escape sequences and \grammarterm{universal-character-name}s
have been replaced\iref{lex.string.uneval}.
\end{note}
This document specifies the semantics for the
\grammarterm{unevaluated-string}{s} \tcode{"C"} and \tcode{"C++"}.
Use of an \grammarterm{unevaluated-string}
other than \tcode{"C"} or \tcode{"C++"} is conditionally-supported,
with \impldef{semantics of linkage specifiers} semantics.
\begin{note}
Therefore, a \grammarterm{linkage-specification} with a language linkage
that is unknown to the implementation requires a diagnostic.
\end{note}

\recommended
The spelling of the language linkage should be taken
from the document defining that language.
For example, \tcode{Ada} (not \tcode{ADA}) and
\tcode{Fortran} or \tcode{FORTRAN}, depending on the vintage.

\pnum
\indextext{specification!linkage!implementation-defined}%
Every implementation shall provide for linkage to the C programming language,
\indextext{C!linkage to}%
\tcode{"C"}, and \Cpp{}, \tcode{"C++"}.
\begin{example}
\begin{codeblock}
complex sqrt(complex);          // \Cpp{} language linkage by default
extern "C" {
  double sqrt(double);          // C language linkage
}
\end{codeblock}
\end{example}

\pnum
A \grammarterm{module-import-declaration} appearing in
a linkage specification with other than \Cpp{} language linkage
is conditionally-supported with
\impldef{support for \grammarterm{module-import-declaration}s
with non-\Cpp{} language linkage} semantics.

\pnum
\indextext{specification!linkage!nesting}%
Linkage specifications nest. When linkage specifications nest, the
innermost one determines the language linkage.
\begin{note}
A linkage specification does not establish a scope.
\end{note}
A \grammarterm{linkage-specification} shall inhabit a namespace scope.
In a \grammarterm{linkage-specification},
the specified language linkage applies
to the function types of all function declarators and
to all functions and variables whose names have external linkage.
\begin{example}
\begin{codeblock}
extern "C"                      // \tcode{f1} and its function type have C language linkage;
  void f1(void(*pf)(int));      // \tcode{pf} is a pointer to a C function

extern "C" typedef void FUNC();
FUNC f2;                        // \tcode{f2} has \Cpp{} language linkage and
                                // its  type has C language linkage

extern "C" FUNC f3;             // \tcode{f3} and its type have C language linkage

void (*pf2)(FUNC*);             // the variable \tcode{pf2} has \Cpp{} language linkage; its type
                                // is ``pointer to \Cpp{} function that takes one parameter of type
                                // pointer to C function''
extern "C" {
  static void f4();             // the name of the function \tcode{f4} has internal linkage,
                                // so \tcode{f4} has no language linkage; its type has C language linkage
}

extern "C" void f5() {
  extern void f4();             // OK, name linkage (internal) and function type linkage (C language linkage)
                                // obtained from previous declaration.
}

extern void f4();               // OK, name linkage (internal) and function type linkage (C language linkage)
                                // obtained from previous declaration.

void f6() {
  extern void f4();             // OK, name linkage (internal) and function type linkage (C language linkage)
                                // obtained from previous declaration.
}
\end{codeblock}
\end{example}
\indextext{class!linkage specification}%
A C language linkage is ignored
in determining the language linkage of
class members,
friend functions with a trailing \grammarterm{requires-clause}, and the
function type of non-static class member functions.
\begin{example}
\begin{codeblock}
extern "C" typedef void FUNC_c();

class C {
  void mf1(FUNC_c*);            // the function \tcode{mf1} and its type have \Cpp{} language linkage;
                                // the parameter has type ``pointer to C function''

  FUNC_c mf2;                   // the function \tcode{mf2} and its type have \Cpp{} language linkage

  static FUNC_c* q;             // the data member \tcode{q} has \Cpp{} language linkage;
                                // its type is ``pointer to C function''
};

extern "C" {
  class X {
    void mf();                  // the function \tcode{mf} and its type have \Cpp{} language linkage
    void mf2(void(*)());        // the function \tcode{mf2} has \Cpp{} language linkage;
                                // the parameter has type ``pointer to C function''
  };
}
\end{codeblock}
\end{example}

\pnum
If two declarations of an entity give it different language linkages, the
program is ill-formed; no diagnostic is required if neither declaration
is reachable from the other.
\indextext{consistency!linkage specification}%
A redeclaration of an entity without a linkage specification
inherits the language linkage of the entity and (if applicable) its type.

\pnum
\indextext{function!linkage specification overloaded}%
Two declarations declare the same entity
if they (re)introduce the same name,
one declares a function or variable with C language linkage,
and the other declares such an entity or declares a variable
that belongs to the global scope.
\begin{example}
\begin{codeblock}
int x;
namespace A {
  extern "C" int f();
  extern "C" int g() { return 1; }
  extern "C" int h();
  extern "C" int x();               // error: same name as global-space object \tcode{x}
}

namespace B {
  extern "C" int f();               // \tcode{A::f} and \tcode{B::f} refer to the same function
  extern "C" int g() { return 1; }  // error: the function \tcode{g} with C language linkage has two definitions
}

int A::f() { return 98; }           // definition for the function \tcode{f} with C language linkage
extern "C" int h() { return 97; }   // definition for the function \tcode{h} with C language linkage
                                    // \tcode{A::h} and \tcode{::h} refer to the same function
\end{codeblock}
\end{example}

\pnum
A declaration directly contained in a
\grammarterm{linkage-specification}
is treated as if it contains the
\keyword{extern}
specifier\iref{dcl.stc} for the purpose of determining the linkage of the
declared name and whether it is a definition. Such a declaration shall
not have a \grammarterm{storage-class-specifier}.
\begin{example}
\begin{codeblock}
extern "C" double f();
static double f();                  // error
extern "C" int i;                   // declaration
extern "C" {
  int i;                            // definition
}
extern "C" static void g();         // error
\end{codeblock}
\end{example}

\pnum
\begin{note}
Because the language linkage is part of a function type, when
indirecting through a pointer to C function, the function to
which the resulting lvalue refers is considered a C function.
\end{note}

\pnum
\indextext{object!linkage specification}%
\indextext{linkage!implementation-defined object}%
Linkage from \Cpp{} to entities defined in other languages and to entities
defined in \Cpp{} from other languages is \impldef{linkage of entities between \Cpp{} and other languages} and
language-dependent. Only where the object layout strategies of two
language implementations are similar enough can such linkage be
achieved.%
\indextext{specification!linkage|)}

\rSec1[dcl.attr]{Attributes}%
\indextext{attribute|(}

\rSec2[dcl.attr.grammar]{Attribute syntax and semantics}

\pnum
\indextext{attribute!syntax and semantics}%
Attributes and annotations specify additional information for various source constructs
such as types, variables, names, contract assertions, blocks, or translation units.

\begin{bnf}
\nontermdef{attribute-specifier-seq}\br
  attribute-specifier \opt{attribute-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{attribute-specifier}\br
  \terminal{[} \terminal{[} \opt{attribute-using-prefix} attribute-list \terminal{]} \terminal{]}\br
  \terminal{[} \terminal{[} annotation-list \terminal{]} \terminal{]}\br
  alignment-specifier
\end{bnf}

\begin{bnf}
\nontermdef{alignment-specifier}\br
  \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br
  \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{attribute-using-prefix}\br
  \keyword{using} attribute-namespace \terminal{:}
\end{bnf}

\begin{bnf}
\nontermdef{attribute-list}\br
  \opt{attribute}\br
  attribute-list \terminal{,} \opt{attribute}\br
  attribute \terminal{...}\br
  attribute-list \terminal{,} attribute \terminal{...}
\end{bnf}

\begin{bnf}
\nontermdef{annotation-list}\br
  annotation \opt{\terminal{...}}\br
  annotation-list \terminal{,} annotation \opt{\terminal{...}}
\end{bnf}

\begin{bnf}
\nontermdef{attribute}\br
    attribute-token \opt{attribute-argument-clause}
\end{bnf}

\begin{bnf}
\nontermdef{annotation}\br
    \terminal{=} constant-expression
\end{bnf}

\begin{bnf}
\nontermdef{attribute-token}\br
    identifier\br
    attribute-scoped-token
\end{bnf}

\begin{bnf}
\nontermdef{attribute-scoped-token}\br
    attribute-namespace \terminal{::} identifier
\end{bnf}

\begin{bnf}
\nontermdef{attribute-namespace}\br
    identifier
\end{bnf}

\begin{bnf}
\nontermdef{attribute-argument-clause}\br
    \terminal{(} \opt{balanced-token-seq} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{balanced-token-seq}\br
    balanced-token \opt{balanced-token-seq}
\end{bnf}

\begin{bnf}
\microtypesetup{protrusion=false}
\nontermdef{balanced-token}\br
    \terminal{(} \opt{balanced-token-seq} \terminal{)}\br
    \terminal{[} \opt{balanced-token-seq} \terminal{]}\br
    \terminal{\{} \opt{balanced-token-seq} \terminal{\}}\br
    \terminal{[:} \opt{balanced-token-seq} \terminal{:]}\br
    \textnormal{any \grammarterm{token} other than \terminal{(}, \terminal{)}, \terminal{[}, \terminal{]}, \terminal{\{}, \terminal{\}}, \terminal{[:}, or \terminal{:]}}
\end{bnf}

\pnum
If an \grammarterm{attribute-specifier}
contains an \grammarterm{attribute-using-prefix},
the \grammarterm{attribute-list} following that \grammarterm{attribute-using-prefix}
shall not contain an \grammarterm{attribute-scoped-token}
and every \grammarterm{attribute-token} in that \grammarterm{attribute-list}
is treated as if
its \grammarterm{identifier} were prefixed with \tcode{N::},
where \tcode{N} is the \grammarterm{attribute-namespace}
specified in the \grammarterm{attribute-using-prefix}.
\begin{note}
This rule imposes no constraints on how
an \grammarterm{attribute-using-prefix}
affects the tokens in an \grammarterm{attribute-argument-clause}.
\end{note}
\begin{example}
\begin{codeblock}
[[using CC: opt(1), debug]]         // same as \tcode{[[CC::opt(1), CC::debug]]}
  void f() {}
[[using CC: opt(1)]] [[CC::debug]]  // same as \tcode{[[CC::opt(1)]] [[CC::debug]]}
  void g() {}
[[using CC: CC::opt(1)]]            // error: cannot combine \tcode{using} and scoped attribute token
  void h() {}
\end{codeblock}
\end{example}

\pnum
\begin{note}
For each individual attribute, the form of the
\grammarterm{balanced-token-seq} will be specified.
\end{note}

\pnum
In an \grammarterm{attribute-list}, an ellipsis may appear only if that
\grammarterm{attribute}'s specification permits it. An \grammarterm{attribute} followed
by an ellipsis is a pack expansion\iref{temp.variadic}.
An \grammarterm{attribute-specifier} that contains
an \grammarterm{attribute-list} with no \grammarterm{attribute}s
has no 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
of an \grammarterm{identifier}\iref{lex.name} is
contained in
an \grammarterm{attribute-token}, it is considered an identifier. No name
lookup\iref{basic.lookup} is performed on any of the identifiers contained in an
\grammarterm{attribute-token}. The \grammarterm{attribute-token} determines additional
requirements on the \grammarterm{attribute-argument-clause} (if any).

\pnum
\begin{note}
Unless otherwise specified,
an \grammarterm{attribute-token} specified in this document cannot be used
as a macro name\iref{cpp.replace.general}.
\end{note}

\pnum
An \grammarterm{annotation} followed by an ellipsis
is a pack expansion\iref{temp.variadic}.

\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,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
entity or statement, the program is ill-formed. If an \grammarterm{attribute-specifier-seq}
appertains to a friend declaration\iref{class.friend}, that declaration shall be a
definition.
\begin{note}
An \grammarterm{attribute-specifier-seq} cannot appertain to
an explicit instantiation\iref{temp.explicit}.
\end{note}

\pnum
For an \grammarterm{attribute-token}
(including an \grammarterm{attribute-scoped-token})
not specified in this document, the
behavior is \impldef{behavior of non-standard attributes};
any such \grammarterm{attribute-token} that is not recognized by the implementation
is ignored.
\begin{note}
A program is ill-formed if it contains an \grammarterm{attribute}
specified in \ref{dcl.attr} that violates
the rules specifying to which entity or statement the attribute can apply or
the syntax rules for the attribute's \grammarterm{attribute-argument-clause}, if any.
\end{note}
\begin{note}
The \grammarterm{attribute}{s} specified in \ref{dcl.attr}
have optional semantics:
given a well-formed program,
removing all instances of any one of those \grammarterm{attribute}{s}
results in a program whose set of possible executions\iref{intro.abstract}
for a given input is
a subset of those of the original program for the same input,
absent implementation-defined guarantees
with respect to that \grammarterm{attribute}.
\end{note}
An \grammarterm{attribute-token} is reserved for future standardization if
\begin{itemize}
\item it is not an \grammarterm{attribute-scoped-token} and
is not specified in this document, or
\item it is an \grammarterm{attribute-scoped-token} and
its \grammarterm{attribute-namespace} is
\tcode{std} followed by zero or more digits.
\end{itemize}
Each implementation should choose a distinctive name for the
\grammarterm{attribute-namespace} in an \grammarterm{attribute-scoped-token}.

\pnum
Two consecutive left square bracket tokens shall appear only
when introducing an \grammarterm{attribute-specifier} or
within the \grammarterm{balanced-token-seq} of
an \grammarterm{attribute-argument-clause}.
\begin{note}
If two consecutive left square brackets appear
where an \grammarterm{attribute-specifier} is not allowed, the program is ill-formed even
if the brackets match an alternative grammar production.
\end{note}
\begin{example}
\begin{codeblock}
int p[10];
void f() {
  int x = 42, y[5];
  int(p[[x] { return x; }()]);  // error: invalid attribute on a nested \grammarterm{declarator-id} and
                                // not a function-style cast of an element of \tcode{p}.
  y[[] { return 2; }()] = 2;    // error even though attributes are not allowed in this context.
  int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.
}
\end{codeblock}
\end{example}

\rSec2[dcl.align]{Alignment specifier}%
\indextext{attribute!alignment}
\indextext{\idxcode{alignas}}

\pnum
An \grammarterm{alignment-specifier}
may be applied to a variable
or to a class data member, but it shall not be applied to a bit-field, a function
parameter, or an \grammarterm{exception-declaration}\iref{except.handle}.
An \grammarterm{alignment-specifier} may also be applied to the declaration
of a class (in an
\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} or
\grammarterm{class-head}\iref{class}, respectively).
An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}.

\pnum
When the \grammarterm{alignment-specifier} is of the form
\tcode{alignas(} \grammarterm{constant-expression} \tcode{)}:
\begin{itemize}
\item the \grammarterm{constant-expression} shall be an integral constant expression

\item if the constant expression does not evaluate to an alignment
value\iref{basic.align}, or evaluates to an extended alignment and
the implementation does not support that alignment in the context of the
declaration, the program is ill-formed.
\end{itemize}

\pnum
An \grammarterm{alignment-specifier} of the form
\tcode{alignas(} \grammarterm{type-id} \tcode{)} has the same
effect as \tcode{alignas(\brk{}alignof(} \grammarterm{type-id}~\tcode{))}\iref{expr.alignof}.

\pnum
The alignment requirement of an entity is the strictest nonzero alignment
specified by its \grammarterm{alignment-specifier}{s}, if any;
otherwise, the \grammarterm{alignment-specifier}{s} have no effect.

\pnum
The combined effect of all \grammarterm{alignment-specifier}{s} in a declaration shall not
specify an alignment that is less strict than the alignment that would
be required for the entity being declared if all \grammarterm{alignment-specifier}{s}
appertaining to that entity
were omitted.
\begin{example}
\begin{codeblock}
struct alignas(8) S {};
struct alignas(1) U {
  S s;
};  // error: \tcode{U} specifies an alignment that is less strict than if the \tcode{alignas(1)} were omitted.
\end{codeblock}
\end{example}

\pnum
If the defining declaration of an entity has an
\grammarterm{alignment-specifier}{}, any non-defining
declaration of that entity shall either specify equivalent alignment or have no
\grammarterm{alignment-specifier}{}.
Conversely, if any declaration of an entity has an
\grammarterm{alignment-specifier}{},
every defining
declaration of that entity shall specify an equivalent alignment.
No diagnostic is required if declarations of an entity have
different \grammarterm{alignment-specifier}{s}
in different translation units.
\begin{example}
\begin{codeblock}
// Translation unit \#1:
struct S { int x; } s, *p = &s;

// Translation unit \#2:
struct alignas(16) S;           // ill-formed, no diagnostic required: definition of \tcode{S} lacks alignment
extern S* p;
\end{codeblock}
\end{example}

\pnum
\begin{example}
An aligned buffer with an alignment requirement
of \tcode{A} and holding \tcode{N} elements of type \tcode{T}
can be declared as:
\begin{codeblock}
alignas(T) alignas(A) T buffer[N];
\end{codeblock}
Specifying \tcode{alignas(T)} ensures
that the final requested alignment will not be weaker than \tcode{alignof(T)},
and therefore the program will not be ill-formed.
\end{example}

\pnum
\begin{example}
\begin{codeblock}
alignas(double) void f();                           // error: alignment applied to function
alignas(double) unsigned char c[sizeof(double)];    // array of characters, suitably aligned for a \tcode{double}
extern unsigned char c[sizeof(double)];             // no \tcode{alignas} necessary
alignas(float)
  extern unsigned char c[sizeof(double)];           // error: different alignment in declaration
\end{codeblock}
\end{example}

\rSec2[dcl.attr.assume]{Assumption attribute}

\pnum
The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement;
such a statement is an \defn{assumption}.
An \grammarterm{attribute-argument-clause} shall be present and
shall have the form:
\begin{ncsimplebnf}
\terminal{(} conditional-expression \terminal{)}
\end{ncsimplebnf}
The expression is contextually converted to \tcode{bool}\iref{conv.general}.
The expression is not evaluated.
If the converted expression would evaluate to \tcode{true}
at the point where the assumption appears,
the assumption has no effect.
Otherwise,
evaluation of the assumption has runtime-undefined behavior.

\pnum
\begin{note}
The expression is potentially evaluated\iref{basic.def.odr}.
The use of assumptions is intended to allow implementations
to analyze the form of the expression and
deduce information used to optimize the program.
Implementations are not required to deduce
any information from any particular assumption.
It is expected that the value of
a \grammarterm{has-attribute-expression} for the \tcode{assume} attribute
is \tcode{0}
if an implementation does not attempt to deduce
any such information from assumptions.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
int divide_by_32(int x) {
  [[assume(x >= 0)]];
  return x/32;                  // The instructions produced for the division
                                // may omit handling of negative values.
}
int f(int y) {
  [[assume(++y == 43)]];        // \tcode{y} is not incremented
  return y;                     // statement may be replaced with \tcode{return 42;}
}
\end{codeblock}
\end{example}

\rSec2[dcl.attr.deprecated]{Deprecated attribute}%
\indextext{attribute!deprecated}

\pnum
The \grammarterm{attribute-token} \tcode{deprecated} can be used to mark names and entities
whose use is still allowed, but is discouraged for some reason.
\begin{note}
In particular,
\tcode{deprecated} is appropriate for names and entities that are deemed obsolescent or
unsafe.
\end{note}
An
\grammarterm{attribute-argument-clause} may be present and, if present, it shall have the form:
\begin{ncbnf}
\terminal{(} unevaluated-string \terminal{)}
\end{ncbnf}
\begin{note}
The \grammarterm{unevaluated-string} in the \grammarterm{attribute-argument-clause}
can be used to explain the rationale for deprecation and/or to suggest a replacing entity.
\end{note}

\pnum
The attribute may be applied to the declaration of
a class,
a type alias,
a variable,
a non-static data member,
a function,
a namespace,
an enumeration,
an enumerator,
a concept, or
a template specialization.

\pnum
An entity declared without the \tcode{deprecated} attribute can later be redeclared
with the attribute and vice-versa.
\begin{note}
Thus, an entity initially declared without the
attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity
is marked as deprecated, later redeclarations do not un-deprecate the entity.
\end{note}
Redeclarations using different forms of the attribute (with or without the
\grammarterm{attribute-argument-clause} or with different
\grammarterm{attribute-argument-clause}{s}) are allowed.

\pnum
\recommended
Implementations should use the \tcode{deprecated} attribute to produce a diagnostic
message in case the program refers to a name or entity other than to declare it, after a
declaration that specifies the attribute. The diagnostic message should include the text provided
within the \grammarterm{attribute-argument-clause} of any \tcode{deprecated} attribute applied
to the name or entity.
The value of
a \grammarterm{has-attribute-expression} for the \tcode{deprecated} attribute
should be \tcode{0}
unless the implementation can issue such diagnostic messages.

\rSec2[dcl.attr.fallthrough]{Fallthrough attribute}
\indextext{attribute!fallthrough}

\pnum
The \grammarterm{attribute-token} \tcode{fallthrough}
may be applied to a null statement\iref{stmt.expr};
such a statement is a \defnadj{fallthrough}{statement}.
No \grammarterm{attribute-argument-clause} shall be present.
A fallthrough statement may only appear within
an enclosing \keyword{switch} statement\iref{stmt.switch}.
The next statement that would be executed after a fallthrough statement
shall be a labeled statement whose label is a case label or
default label for the same \keyword{switch} statement and,
if the fallthrough statement is contained in an iteration statement,
the next statement shall be part of the same execution of
the substatement of the innermost enclosing iteration statement.
The program is ill-formed if there is no such statement.
The innermost enclosing \tcode{switch} statement
of a fallthrough statement $S$ shall be contained in
the innermost enclosing expansion statement\iref{stmt.expand} of $S$, if any.

\pnum
\recommended
The use of a fallthrough statement should suppress
a warning that an implementation might otherwise issue
for a case or default label that is reachable
from another case or default label along some path of execution.
The value of
a \grammarterm{has-attribute-expression} for the \tcode{fallthrough} attribute
should be \tcode{0}
if the attribute does not cause suppression of such warnings.
Implementations should issue a warning
if a fallthrough statement is not dynamically reachable.

\pnum
\begin{example}
\begin{codeblock}
void f(int n) {
  void g(), h(), i();
  switch (n) {
  case 1:
  case 2:
    g();
    [[fallthrough]];
  case 3:                       // warning on fallthrough discouraged
    do {
      [[fallthrough]];          // error: next statement is not part of the same substatement execution
    } while (false);
  case 6:
    do {
      [[fallthrough]];          // error: next statement is not part of the same substatement execution
    } while (n--);
  case 7:
    while (false) {
      [[fallthrough]];          // error: next statement is not part of the same substatement execution
    }
  case 5:
    h();
  case 4:                       // implementation may warn on fallthrough
    i();
    [[fallthrough]];            // error
  }
}
\end{codeblock}
\end{example}

\rSec2[dcl.attr.indet]{Indeterminate storage}
\indextext{attribute!indeterminate}

\pnum
The \grammarterm{attribute-token} \tcode{indeterminate} may be applied
to the definition of a block variable with automatic storage duration or
to a \grammarterm{parameter-declaration} of a function declaration.
No \grammarterm{attribute-argument-clause} shall be present.
The attribute specifies
that the storage of an object with automatic storage duration
is initially indeterminate rather than erroneous\iref{basic.indet}.

\pnum
If a function parameter is declared with the \tcode{indeterminate} attribute,
it shall be so declared in the first declaration of its function.
If a function parameter is declared with
the \tcode{indeterminate} attribute in the first declaration of its function
in one translation unit and
the same function is declared without the \tcode{indeterminate} attribute
on the same parameter in its first declaration in another translation unit,
the program is ill-formed, no diagnostic required.

\pnum
\begin{note}
Reading from an uninitialized variable
that is marked \tcode{[[indeterminate]]} can cause undefined behavior.
\begin{codeblock}
void f(int);
void g() {
  int x [[indeterminate]], y;
  f(y);                 // erroneous behavior\iref{basic.indet}
  f(x);                 // undefined behavior
}

struct T {
  T() {}
  int x;
};
int h(T t [[indeterminate]]) {
  f(t.x);               // undefined behavior when called below
  return 0;
}
int _ = h(T());
\end{codeblock}
\end{note}

\rSec2[dcl.attr.likelihood]{Likelihood attributes}%
\indextext{attribute!likely}
\indextext{attribute!unlikely}

\pnum
The \grammarterm{attribute-token}s
\tcode{likely} and \tcode{unlikely}
may be applied to labels or statements.
No \grammarterm{attribute-argument-clause} shall be present.
The \grammarterm{attribute-token} \tcode{likely}
shall not appear in an \grammarterm{attribute-specifier-seq}
that contains the \grammarterm{attribute-token} \tcode{unlikely}.

\pnum
\begin{note}
The use of the \tcode{likely} attribute
is intended to allow implementations to optimize for
the case where paths of execution including it
are arbitrarily more likely
than any alternative path of execution
that does not include such an attribute on a statement or label.
The use of the \tcode{unlikely} attribute
is intended to allow implementations to optimize for
the case where paths of execution including it
are arbitrarily more unlikely
than any alternative path of execution
that does not include such an attribute on a statement or label.
It is expected that the value of a \grammarterm{has-attribute-expression}
for the \tcode{likely} and \tcode{unlikely} attributes
is \tcode{0}
if the implementation does not attempt to use these attributes
for such optimizations.
A path of execution includes a label
if and only if it contains a jump to that label.
\end{note}
\begin{note}
Excessive usage of either of these attributes
is liable to result in performance degradation.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
void g(int);
int f(int n) {
  if (n > 5) [[unlikely]] {     // \tcode{n > 5} is considered to be arbitrarily unlikely
    g(0);
    return n * 2 + 1;
  }

  switch (n) {
  case 1:
    g(1);
    [[fallthrough]];

  [[likely]] case 2:            // \tcode{n == 2} is considered to be arbitrarily more
    g(2);                       // likely than any other value of \tcode{n}
    break;
  }
  return 3;
}
\end{codeblock}
\end{example}

\rSec2[dcl.attr.unused]{Maybe unused attribute}%
\indextext{attribute!maybe unused}

\pnum
The \grammarterm{attribute-token} \tcode{maybe_unused}
indicates that a name, label, or entity is possibly intentionally unused.
No \grammarterm{attribute-argument-clause} shall be present.

\pnum
The attribute may be applied to the declaration of a class,
type alias,
variable (including a structured binding declaration),
structured binding,
result binding\iref{dcl.contract.res},
non-static data member,
function,
enumeration, or
enumerator, or
to an \grammarterm{identifier} label\iref{stmt.label}.

\pnum
A name or entity declared without the \tcode{maybe_unused} attribute
can later be redeclared with the attribute
and vice versa.
An entity is considered marked
after the first declaration that marks it.

\pnum
\recommended
For an entity marked \tcode{maybe_unused},
implementations should not emit a warning
that the entity or its structured bindings (if any)
are used or unused.
For a structured binding declaration not marked \tcode{maybe_unused},
implementations should not emit such a warning unless
all of its structured bindings are unused.
For a label to which \tcode{maybe_unused} is applied,
implementations should not emit a warning that the label is used or unused.
The value of
a \grammarterm{has-attribute-expression} for the \tcode{maybe_unused} attribute
should be \tcode{0}
if the attribute does not cause suppression of such warnings.

\pnum
\begin{example}
\begin{codeblock}
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
                        [[maybe_unused]] bool thing2) {
  [[maybe_unused]] bool b = thing1 && thing2;
  assert(b);
#ifdef NDEBUG
  goto x;
#endif
  [[maybe_unused]] x:
}
\end{codeblock}
Implementations should not warn that \tcode{b} or \tcode{x} is unused,
whether or not \tcode{NDEBUG} is defined.
\end{example}

\rSec2[dcl.attr.nodiscard]{Nodiscard attribute}%
\indextext{attribute!nodiscard}

\pnum
The \grammarterm{attribute-token} \tcode{nodiscard}
may be applied to a function or a lambda call operator or
to the declaration of a class or enumeration.
An \grammarterm{attribute-argument-clause} may be present
and, if present, shall have the form:

\begin{ncbnf}
\terminal{(} unevaluated-string \terminal{)}
\end{ncbnf}

\pnum
A name or entity declared without the \tcode{nodiscard} attribute
can later be redeclared with the attribute and vice-versa.
\begin{note}
Thus, an entity initially declared without the attribute
can be marked as \tcode{nodiscard}
by a subsequent redeclaration.
However, after an entity is marked as \tcode{nodiscard},
later redeclarations do not remove the \tcode{nodiscard}
from the entity.
\end{note}
Redeclarations using different forms of the attribute
(with or without the \grammarterm{attribute-argument-clause}
or with different \grammarterm{attribute-argument-clause}s)
are allowed.

\pnum
A \defnadj{nodiscard}{type} is
a (possibly cv-qualified) class or enumeration type
marked \tcode{nodiscard} in a reachable declaration.
A \defnadj{nodiscard}{call} is either
\begin{itemize}
\item
  a function call expression\iref{expr.call}
  that calls a function declared \tcode{nodiscard} in a reachable declaration or
  whose return type is a nodiscard type, or
\item
  an explicit type
  conversion\iref{expr.type.conv,expr.static.cast,expr.cast}
  that constructs an object through
  a constructor declared \tcode{nodiscard} in a reachable declaration, or
  that initializes an object of a nodiscard type.
\end{itemize}

\pnum
\recommended
Appearance of a nodiscard call as
a potentially evaluated discarded-value expression\iref{expr.prop}
of non-void type
is discouraged unless explicitly cast to \keyword{void}.
Implementations should issue a warning in such cases.
The value of
a \grammarterm{has-attribute-expression} for the \tcode{nodiscard} attribute
should be \tcode{0} unless the implementation can issue such warnings.
\begin{note}
This is typically because discarding the return value
of a nodiscard call has surprising consequences.
\end{note}
The \grammarterm{unevaluated-string}
in a \tcode{nodiscard} \grammarterm{attribute-argument-clause}
should be used in the message of the warning
as the rationale for why the result should not be discarded.

\pnum
\begin{example}
\begin{codeblock}
struct [[nodiscard]] my_scopeguard { @\commentellip@ };
struct my_unique {
  my_unique() = default;                                // does not acquire resource
  [[nodiscard]] my_unique(int fd) { @\commentellip@ }         // acquires resource
  ~my_unique() noexcept { @\commentellip@ }                   // releases resource, if any
  @\commentellip@
};
struct [[nodiscard]] error_info { @\commentellip@ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
  my_scopeguard();              // warning encouraged
  (void)my_scopeguard(),        // warning not encouraged, cast to \keyword{void}
    launch_missiles();          // comma operator, statement continues
  my_unique(42);                // warning encouraged
  my_unique();                  // warning not encouraged
  enable_missile_safety_mode(); // warning encouraged
  launch_missiles();
}
error_info &foo();
void f() { foo(); }             // warning not encouraged: not a nodiscard call, because neither
                                // the (reference) return type nor the function is declared nodiscard
\end{codeblock}
\end{example}

\rSec2[dcl.attr.noreturn]{Noreturn attribute}%
\indextext{attribute!noreturn}

\pnum
The \grammarterm{attribute-token} \tcode{noreturn} specifies that a function does not return.
No \grammarterm{attribute-argument-clause} shall be present.
The attribute may be applied to a function or a lambda call operator.
The first declaration of a function shall
specify the \tcode{noreturn} attribute if any declaration of that function specifies the
\tcode{noreturn} attribute. If a function is declared with the \tcode{noreturn} attribute in one
translation unit and the same function is declared without the \tcode{noreturn} attribute in another
translation unit, the program is ill-formed, no diagnostic required.

\pnum
If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn}
attribute and that invocation eventually returns,
the behavior is runtime-undefined.
\begin{note}
The function can
terminate by throwing an exception.
\end{note}

\pnum
\recommended
Implementations should issue a
warning if a function marked \tcode{[[noreturn]]} might return.
The value of
a \grammarterm{has-attribute-expression} for the \tcode{noreturn} attribute
should be \tcode{0} unless the implementation can issue such warnings.

\pnum
\begin{example}
\begin{codeblock}
[[ noreturn ]] void f() {
  throw "error";                // OK
}

[[ noreturn ]] void q(int i) {  // behavior is undefined if called with an argument \tcode{<= 0}
  if (i > 0)
    throw "positive";
}
\end{codeblock}
\end{example}

\rSec2[dcl.attr.nouniqueaddr]{No unique address attribute}%
\indextext{attribute!no unique address}

\pnum
The \grammarterm{attribute-token} \tcode{no_unique_address}
specifies that a non-static data member
is a potentially-overlapping subobject\iref{intro.object}.
No \grammarterm{attribute-argument-clause} shall be present.
The attribute may appertain to a non-static data member
other than a bit-field.

\pnum
\begin{note}
The non-static data member can share the address of
another non-static data member or that of a base class,
and any padding that would normally be inserted
at the end of the object
can be reused as storage for other members.
\end{note}

\recommended
The value of a \grammarterm{has-attribute-expression}
for the \tcode{no_unique_address} attribute
should be \tcode{0} for a given implementation
unless this attribute can cause a potentially-overlapping subobject
to have zero size.

\begin{example}
\begin{codeblock}
template<typename Key, typename Value,
         typename Hash, typename Pred, typename Allocator>
class hash_map {
  [[no_unique_address]] Hash hasher;
  [[no_unique_address]] Pred pred;
  [[no_unique_address]] Allocator alloc;
  Bucket *buckets;
  // ...
public:
  // ...
};
\end{codeblock}
Here, \tcode{hasher}, \tcode{pred}, and \tcode{alloc}
could have the same address as \tcode{buckets}
if their respective types are all empty.
\end{example}

\rSec2[dcl.attr.annotation]{Annotations}%
\indextext{attribute!annotations}

\pnum
An annotation may be applied
to a \grammarterm{base-specifier} or
to a declaration $D$ of a
type,
type alias,
variable,
function,
function parameter of non-\tcode{void} type,
namespace,
enumerator, or
non-static data member,
unless
\begin{itemize}
\item the host scope of $X$ differs from its target scope or
\item $X$ is a non-defining friend declaration,
\end{itemize}
where $X$ is
\begin{itemize}
\item
$D'$ if $D$ is a function parameter declaration in
a function declarator\iref{dcl.fct} of a function declaration $D'$ and
\item $D$ otherwise.
\end{itemize}
\begin{note}
An annotation on a \grammarterm{parameter-declaration} in a function definition
applies to both the function parameter and the variable.
\begin{example}
\begin{codeblock}
void f([[=1]] int x);
void f([[=2]] int y) {
  constexpr auto rp = parameters_of(@\reflexpr{f}@)[0];
  constexpr auto ry = variable_of(rp);
  static_assert(ry == ^^y);

  static_assert(annotations_of(rp).size() == 2);    // both \tcode{[1, 2]}
  static_assert(annotations_of(ry).size() == 1);    // just \tcode{[2]}
  static_assert(annotations_of(rp)[1] == annotations_of(ry)[0]);
}
\end{codeblock}
\end{example}
\end{note}

\pnum
Let $E$ be the expression
\tcode{std::meta::reflect_constant(\grammarterm{constant-expression})}.
$E$ shall be a constant expression;
the result of $E$ is the \defnadj{underlying}{constant} of the annotation.

\pnum
Each \grammarterm{annotation} or instantiation thereof
produces a unique annotation.
\begin{example}
\begin{codeblock}
[[=1]] void f();
[[=2, =3, =2]] void g();
void g [[=4, =2]] ();
\end{codeblock}
\tcode{f} has one annotation
and \tcode{g} has five annotations.
These can be queried with metafunctions
such as \tcode{std::\brk{}meta::\brk{}anno\-tations_of}\iref{meta.reflection.annotation}.
\end{example}
\begin{example}
\begin{codeblock}
template<int> int x [[=1]];
static_assert(annotations_of(^^x<0>) != annotations_of(^^x<1>));    // OK
\end{codeblock}
\end{example}

\pnum
Substituting into an \grammarterm{annotation}
is not in the immediate context.
\begin{example}
\begin{codeblock}
template<class T>
  [[=T::type()]] void f(T t);

void f(int);

void g() {
  f(0);         // OK
  f('0');       // error, substituting into the annotation results in an invalid expression
}
\end{codeblock}
\end{example}

\indextext{attribute|)}%
\indextext{declaration|)}
