%!TEX root = std.tex
\rSec0[stmt]{Statements}%
\indextext{statement|(}

\gramSec[gram.stmt]{Statements}

\indextext{block (statement)|see{statement, compound}}

\rSec1[stmt.pre]{Preamble}

\pnum
Except as indicated, statements are executed in sequence\iref{intro.execution}.

\begin{bnf}
\nontermdef{statement}\br
    labeled-statement\br
    \opt{attribute-specifier-seq} expression-statement\br
    \opt{attribute-specifier-seq} compound-statement\br
    \opt{attribute-specifier-seq} selection-statement\br
    \opt{attribute-specifier-seq} iteration-statement\br
    \opt{attribute-specifier-seq} expansion-statement\br
    \opt{attribute-specifier-seq} jump-statement\br
    \opt{attribute-specifier-seq} assertion-statement\br
    declaration-statement\br
    \opt{attribute-specifier-seq} try-block
\end{bnf}

\begin{bnf}
\nontermdef{init-statement}\br
    expression-statement\br
    simple-declaration\br
    alias-declaration
\end{bnf}

\begin{bnf}
\nontermdef{condition}\br
    expression\br
    condition-declaration
\end{bnf}

\begin{bnf}
\nontermdef{condition-declaration}\br
    \opt{attribute-specifier-seq} decl-specifier-seq declarator brace-or-equal-initializer\br
    structured-binding-declaration initializer
\end{bnf}

\begin{bnf}
\nontermdef{for-range-declaration}\br
    \opt{attribute-specifier-seq} decl-specifier-seq declarator\br
    structured-binding-declaration
\end{bnf}

\begin{bnf}
\nontermdef{for-range-initializer}\br
    expr-or-braced-init-list
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} appertains to the respective statement.
See~\ref{dcl.meaning} for the optional \grammarterm{attribute-specifier-seq} in a
\grammarterm{for-range-declaration}.

\pnum
A \defn{substatement} of a \grammarterm{statement} is one of the following:
\begin{itemize}
\item
  for a \grammarterm{labeled-statement}, its \grammarterm{statement},
\item
  for a \grammarterm{compound-statement}, any \grammarterm{statement} of its \grammarterm{statement-seq},
\item
  for a \grammarterm{selection-statement}, any of its \grammarterm{statement}{s} or \grammarterm{compound-statement}{s} (but not its \grammarterm{init-statement}),
\item
  for an \grammarterm{iteration-statement}, its \grammarterm{statement} (but not an \grammarterm{init-statement}), or
\item
  for an \grammarterm{expansion-statement}, its \grammarterm{compound-statement}
  (but not an \grammarterm{init-statement}).
\end{itemize}
\begin{note}
The \grammarterm{compound-statement} of a \grammarterm{lambda-expression}
is not a substatement of the \grammarterm{statement} (if any)
in which the \grammarterm{lambda-expression} lexically appears.
\end{note}

\pnum
\indextext{statement!enclosing}%
A \grammarterm{statement} \tcode{S1} \defnx{encloses}{enclosing statement}
a \grammarterm{statement} \tcode{S2} if
\begin{itemize}
\item
  \tcode{S2} is a substatement of \tcode{S1},
\item
  \tcode{S1} is a \grammarterm{selection-statement},
  \grammarterm{iteration-statement}, or
  \grammarterm{expansion-statement},
  and \tcode{S2} is the \grammarterm{init-statement} of \tcode{S1},
\item
  \tcode{S1} is a \grammarterm{try-block} and \tcode{S2}
  is its \grammarterm{compound-statement} or
  any of the \grammarterm{compound-statement}{s} of
  its \grammarterm{handler}{s}, or
\item
  \tcode{S1} encloses a statement \tcode{S3} and \tcode{S3} encloses \tcode{S2}.
\end{itemize}
\indextext{statement!enclosed by}%
A statement \tcode{S1} is
\defnx{enclosed by}{enclosed by statement}
a statement \tcode{S2} if
\tcode{S2} encloses \tcode{S1}.

\pnum
\indextext{\idxgram{condition}{s}!rules for}%
The rules for \grammarterm{condition}{s} apply both
to \grammarterm{selection-statement}{s}\iref{stmt.select} and
to the \keyword{for} and \keyword{while} statements\iref{stmt.iter}.
If a \grammarterm{structured-binding-declaration}
appears in a \grammarterm{condition},
the \grammarterm{condition} is a structured binding declaration\iref{dcl.pre}.
A \grammarterm{condition} that is
neither an \grammarterm{expression} nor a structured binding declaration
is a declaration\iref{dcl}.
The \grammarterm{declarator} shall not
specify a function or an array. The \grammarterm{decl-specifier-seq} shall not
define a class or enumeration. If the \keyword{auto} \grammarterm{type-specifier} appears in
the \grammarterm{decl-specifier-seq},
the type of the identifier being declared is deduced from the initializer as described in~\ref{dcl.spec.auto}.

\pnum
The \defnadj{decision}{variable} of a \grammarterm{condition}
that is neither an \grammarterm{expression} nor a structured binding declaration
is the declared variable.
The decision variable of a \grammarterm{condition}
that is a structured binding declaration is specified in \ref{dcl.struct.bind}.

\pnum
The value of a \grammarterm{condition} that is not an \grammarterm{expression}
in a statement other than a \keyword{switch} statement is the value of the
decision variable
contextually converted to \tcode{bool}\iref{conv}.
If that
conversion is ill-formed, the program is ill-formed.
The value of a
\grammarterm{condition} that is an expression is the value of the
expression, contextually converted to \tcode{bool}
for statements other
than \keyword{switch};
if that conversion is ill-formed, the program is
ill-formed. The value of the condition will be referred to as simply
``the condition'' where the usage is unambiguous.

\pnum
If a \grammarterm{condition} can be syntactically resolved
as either an \grammarterm{expression} or a \grammarterm{condition-declaration},
it is interpreted as the latter.

\pnum
For any \grammarterm{condition} or \grammarterm{for-range-declaration} $D$,
each \grammarterm{decl-specifier}
in the \grammarterm{decl-specifier-seq} of $D$,
including that of any \grammarterm{structured-binding-declaration} of $D$,
shall be either a \grammarterm{type-specifier}
or \keyword{constexpr}.

\rSec1[stmt.label]{Label}%
\indextext{statement!labeled}

\pnum
\indextext{statement!labeled}%
\indextext{\idxcode{:}!label specifier}%
A label can be added to a statement or
used anywhere in a \grammarterm{compound-statement}.

\begin{bnf}
\nontermdef{label}\br
    \opt{attribute-specifier-seq} identifier \terminal{:}\br
    \opt{attribute-specifier-seq} \keyword{case} constant-expression \terminal{:}\br
    \opt{attribute-specifier-seq} \keyword{default} \terminal{:}
\end{bnf}

\begin{bnf}
\nontermdef{labeled-statement}\br
    label statement
\end{bnf}

The optional \grammarterm{attribute-specifier-seq} appertains to the label.
\indextext{statement!\idxcode{goto}}%
The only use of a label with an \grammarterm{identifier} is
as the target of a \tcode{goto}.
\indextext{label!scope of}%
No two labels in a function shall have the same \grammarterm{identifier}.
A label can be used in a \tcode{goto} statement
before its introduction.

\pnum
\indextext{\idxgram{labeled-statement}}%
\indextext{label!\idxcode{case}}%
\indextext{label!\idxcode{default}}%
A \grammarterm{labeled-statement}
whose \grammarterm{label} is a \keyword{case} or \keyword{default} label
shall be enclosed by\iref{stmt.pre} a \keyword{switch} statement\iref{stmt.switch}.

\pnum
A \defnadj{control-flow-limited}{statement} is a statement \tcode{S} for which:
\begin{itemize}
\item
  a \keyword{case} or \keyword{default} label appearing within \tcode{S} shall
  be associated with a \keyword{switch} statement\iref{stmt.switch} within
  \tcode{S}, and
\item
  a label declared in \tcode{S} shall only be referred to by a
  statement\iref{stmt.goto} in \tcode{S}.
\end{itemize}

\pnum
An identifier label shall not be enclosed
by an \grammarterm{expansion-statement}\iref{stmt.expand}.

\rSec1[stmt.expr]{Expression statement}%
\indextext{statement!expression}

\pnum
Expression statements have the form
\begin{bnf}
\nontermdef{expression-statement}\br
    \opt{expression} \terminal{;}
\end{bnf}

The expression is
a discarded-value expression\iref{expr.context}.
All
\indextext{side effects}%
side effects from an expression statement
are completed before the next statement is executed.
\indextext{statement!empty}%
An expression statement with the \grammarterm{expression} missing is called
a \defnadj{null}{statement}.
\begin{note}
Most statements are expression statements --- usually assignments or
function calls. A null statement is useful to supply a null body to an
iteration statement such as a \keyword{while}
statement\iref{stmt.while}.
\end{note}

\rSec1[stmt.block]{Compound statement or block}%
\indextext{\idxcode{\{\}}!block statement}%

\pnum
A \defnadj{compound}{statement} (also known as a block) groups a
sequence of statements into a single statement.

\begin{bnf}
\nontermdef{compound-statement}\br
    \terminal{\{} \opt{statement-seq} \opt{label-seq} \terminal{\}}
\end{bnf}

\begin{bnf}
\nontermdef{statement-seq}\br
    statement \opt{statement-seq}
\end{bnf}

\begin{bnf}
\nontermdef{label-seq}\br
    label \opt{label-seq}
\end{bnf}

A label at the end of a \grammarterm{compound-statement}
is treated as if it were followed by a null statement.

\pnum
\begin{note}
A compound statement defines a block scope\iref{basic.scope}.
\end{note}

\rSec1[stmt.select]{Selection statements}%
\indextext{statement!selection|(}

\rSec2[stmt.select.general]{General}%

\pnum
Selection statements choose one of several flows of control.

\indextext{statement!\idxcode{if}}%
\indextext{statement!\idxcode{switch}}%
%
\begin{bnf}
\nontermdef{selection-statement}\br
    \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement\br
    \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement \keyword{else} statement\br
    \keyword{if} \opt{\terminal{!}} \keyword{consteval} compound-statement\br
    \keyword{if} \opt{\terminal{!}} \keyword{consteval} compound-statement \keyword{else} statement\br
    \keyword{switch} \terminal{(} \opt{init-statement} condition \terminal{)} statement
\end{bnf}

See~\ref{dcl.meaning} for the optional \grammarterm{attribute-specifier-seq} in a condition.
\begin{note}
An \grammarterm{init-statement} ends with a semicolon.
\end{note}

\pnum
\indextext{scope!\idxgram{selection-statement}}%
\begin{note}
Each \grammarterm{selection-statement} and
each substatement of a \grammarterm{selection-statement}
has a block scope\iref{basic.scope.block}.
\end{note}

\rSec2[stmt.if]{The \keyword{if} statement}%
\indextext{statement!\idxcode{if}}

\pnum
If the condition\iref{stmt.pre} yields \tcode{true}, the first
substatement is executed. If the \keyword{else} part of the selection
statement is present and the condition yields \tcode{false}, the second
substatement is executed. If the first substatement is reached via a
label, the condition is not evaluated and the second substatement is
not executed. In the second form of \keyword{if} statement
(the one including \keyword{else}), if the first substatement is also an
\keyword{if} statement then that inner \tcode{if} statement shall contain
an \keyword{else} part.
\begin{footnote}
In other words, the \keyword{else} is associated with the nearest un-elsed
\keyword{if}.
\end{footnote}

\pnum
If the \keyword{if} statement is of the form \tcode{if constexpr},
the value of the condition
is contextually converted to \keyword{bool} and
the converted expression shall be a constant expression\iref{expr.const.const};
this
form is called a \defn{constexpr if} statement. If the value of the
converted condition is \tcode{false}, the first substatement is a
\defn{discarded statement}, otherwise the second substatement, if
present, is a discarded statement. During the instantiation of an
enclosing templated entity\iref{temp.pre}, if the condition is
not value-dependent after its instantiation, the discarded substatement
(if any) is not instantiated.
Each substatement of a constexpr if statement is a control-flow-limited
statement\iref{stmt.label}.
\begin{example}
\begin{codeblock}
if constexpr (sizeof(int[2])) {}        // OK, narrowing allowed
\end{codeblock}
\end{example}
\begin{note}
Odr-uses\iref{term.odr.use} in a discarded statement do not require
an entity to be defined.
\end{note}
\begin{example}
\begin{codeblock}
template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {
  // ... handle \tcode{p}

  if constexpr (sizeof...(rs) > 0)
    g(rs...);       // never instantiated with an empty argument list
}

extern int x;       // no definition of \tcode{x} required

int f() {
  if constexpr (true)
    return 0;
  else if (x)
    return x;
  else
    return -x;
}
\end{codeblock}
\end{example}

\pnum
An \keyword{if} statement of the form
\begin{ncsimplebnf}
\keyword{if} \opt{\keyword{constexpr}} \terminal{(} init-statement condition \terminal{)} statement
\end{ncsimplebnf}
is equivalent to
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent init-statement\br
\bnfindent \keyword{if} \opt{\keyword{constexpr}} \terminal{(} condition \terminal{)} statement\br
\terminal{\}}
\end{ncsimplebnf}
and an \keyword{if} statement of the form
\begin{ncsimplebnf}
\keyword{if} \opt{\keyword{constexpr}} \terminal{(} init-statement condition \terminal{)} statement \keyword{else} statement
\end{ncsimplebnf}
is equivalent to
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent init-statement\br
\bnfindent \keyword{if} \opt{\keyword{constexpr}} \terminal{(} condition \terminal{)} statement \keyword{else} statement\br
\terminal{\}}
\end{ncsimplebnf}
except that the \grammarterm{init-statement} is
in the same scope as the \grammarterm{condition}.

\pnum
An \keyword{if} statement of the form \tcode{\keyword{if} \keyword{consteval}}
is called a \defnadj{consteval if}{statement}.
The \grammarterm{statement}, if any, in a consteval if statement
shall be a \grammarterm{compound-statement}.
\begin{example}
\begin{codeblock}
constexpr void f(bool b) {
  if (true)
    if consteval { }
    else ;              // error: not a \grammarterm{compound-statement}; \keyword{else} not associated with outer \keyword{if}
}
\end{codeblock}
\end{example}

\pnum
If a consteval if statement is evaluated in a context
that is manifestly constant-evaluated\iref{expr.const.defns},
the first substatement is executed.
\begin{note}
The first substatement is an immediate function context.
\end{note}
Otherwise, if the \keyword{else} part of the selection statement is present,
then the second substatement is executed.
Each substatement of a consteval if statement is a control-flow-limited
statement\iref{stmt.label}.

\pnum
An \keyword{if} statement of the form
\begin{ncsimplebnf}
\keyword{if} \terminal{!} \keyword{consteval} compound-statement
\end{ncsimplebnf}
is not itself a consteval if statement,
but is equivalent to the consteval if statement
\begin{ncsimplebnf}
\keyword{if} \keyword{consteval} \terminal{\{} \terminal{\}} \keyword{else} compound-statement
\end{ncsimplebnf}
An \keyword{if} statement of the form
\begin{ncsimplebnf}
\keyword{if} \terminal{!} \keyword{consteval} compound-statement$_1$ \keyword{else} statement$_2$
\end{ncsimplebnf}
is not itself a consteval if statement,
but is equivalent to the consteval if statement
\begin{ncsimplebnf}
\keyword{if} \keyword{consteval} statement$_2$ \keyword{else} compound-statement$_1$
\end{ncsimplebnf}

\rSec2[stmt.switch]{The \keyword{switch} statement}%
\indextext{statement!\idxcode{switch}}

\pnum
The \keyword{switch} statement causes control to be transferred to one of
several statements depending on the value of a condition.

\pnum
If the \grammarterm{condition} is an \grammarterm{expression},
the value of the condition is the value of the \grammarterm{expression};
otherwise, it is the value of the decision variable.
The value of the condition shall be of integral type, enumeration type, or class
type. If of class type, the
condition is contextually implicitly converted\iref{conv} to
an integral or enumeration type.
If the (possibly converted) type is subject to integral
promotions\iref{conv.prom}, the condition is converted
to the promoted type.
Any
statement within the \keyword{switch} statement can be labeled with one or
more case labels as follows:
\begin{ncbnf}
\indextext{label!\idxcode{case}}%
\keyword{case} constant-expression \terminal{:}
\end{ncbnf}
where the \grammarterm{constant-expression} shall be
a converted constant expression\iref{expr.const.const} of the
adjusted type of the switch condition. No two of the case constants in
the same switch shall have the same value after conversion.

\pnum
\indextext{label!\idxcode{default}}%
There shall be at most one label of the form
\begin{codeblock}
default :
\end{codeblock}
within a \keyword{switch} statement.

\pnum
Switch statements can be nested; a \keyword{case} or \keyword{default} label
is associated with the smallest switch enclosing it.

\pnum
When the \keyword{switch} statement is executed, its condition is
evaluated.
\indextext{label!\idxcode{case}}%
If one of the case constants has the same value as the condition,
control is passed to the statement following the matched case label. If
no case constant matches the condition, and if there is a
\indextext{label!\idxcode{default}}%
\keyword{default} label, control passes to the statement labeled by the
default label. If no case matches and if there is no \keyword{default}
then none of the statements in the switch is executed.

\pnum
\keyword{case} and \keyword{default} labels in themselves do not alter the
flow of control, which continues unimpeded across such labels. To exit
from a switch, see \keyword{break}, \ref{stmt.break}.
\begin{note}
Usually, the substatement that is the subject of a switch is compound
and \keyword{case} and \keyword{default} labels appear on the top-level
statements contained within the (compound) substatement, but this is not
required.
\indextext{statement!declaration in \tcode{switch}}%
Declarations can appear in the substatement of a
\keyword{switch} statement.
\end{note}

\pnum
A \keyword{switch} statement of the form
\begin{ncsimplebnf}
\keyword{switch} \terminal{(} init-statement condition \terminal{)} statement
\end{ncsimplebnf}
is equivalent to
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent init-statement\br
\bnfindent \keyword{switch} \terminal{(} condition \terminal{)} statement\br
\terminal{\}}
\end{ncsimplebnf}
except that the \grammarterm{init-statement} is in
the same scope as the \grammarterm{condition}.

\indextext{statement!selection|)}

\rSec1[stmt.iter]{Iteration statements}%
\indextext{statement!iteration|(}

\rSec2[stmt.iter.general]{General}%

\pnum
Iteration statements specify looping.

\indextext{statement!\idxcode{while}}%
\indextext{statement!\idxcode{do}}%
\indextext{statement!\idxcode{for}}%
%
\begin{bnf}
\nontermdef{iteration-statement}\br
    \keyword{while} \terminal{(} condition \terminal{)} statement\br
    \keyword{do} statement \keyword{while} \terminal{(} expression \terminal{)} \terminal{;}\br
    \keyword{for} \terminal{(} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement\br
    \keyword{for} \terminal{(} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement
\end{bnf}

\begin{note}
An \grammarterm{init-statement} ends with a semicolon.
\end{note}

\pnum
\indextext{scope!\idxgram{iteration-statement}}%
The substatement in an \grammarterm{iteration-statement} implicitly defines
a block scope\iref{basic.scope} which is entered and exited each time
through the loop.
If the substatement in an \grammarterm{iteration-statement} is
a single statement and not a \grammarterm{compound-statement},
it is as if it was rewritten to be
a \grammarterm{compound-statement} containing the original statement.
\begin{example}
\begin{codeblock}
while (--x >= 0)
  int i;
\end{codeblock}
can be equivalently rewritten as
\begin{codeblock}
while (--x >= 0) {
  int i;
}
\end{codeblock}
Thus after the \keyword{while} statement, \tcode{i} is no longer in scope.
\end{example}

\pnum
A \defnadj{trivially empty}{iteration statement} is
an iteration statement matching one of the following forms:
\begin{itemize}
\item \tcode{while (} \grammarterm{expression} \tcode{) ;}
\item \tcode{while (} \grammarterm{expression} \tcode{) \{ \}}
\item \tcode{do ; while (} \grammarterm{expression} \tcode{) ;}
\item \tcode{do \{ \} while (} \grammarterm{expression} \tcode{) ;}
\item \tcode{for (} \grammarterm{init-statement} \opt{\grammarterm{expression}} \tcode{; ) ;}
\item \tcode{for (} \grammarterm{init-statement} \opt{\grammarterm{expression}} \tcode{; ) \{ \}}
\end{itemize}
The \defnadj{controlling}{expression} of a trivially empty iteration statement
is the \grammarterm{expression} of
a \tcode{while}, \tcode{do}, or \tcode{for} statement
(or \tcode{true}, if the \tcode{for} statement has no \grammarterm{expression}).
A \defnadj{trivial infinite}{loop} is a trivially empty iteration statement
for which the converted controlling expression is a constant expression,
when interpreted as a \grammarterm{constant-expression}\iref{expr.const.const}, and
evaluates to \tcode{true}.
The \grammarterm{statement} of a trivial infinite loop is replaced with
a call to the function \tcode{std::this_thread::yield}\iref{thread.thread.this};
it is \impldef{whether freestanding implementations replace the \grammarterm{statement}
of a trivial infinite loop with a call to the function \tcode{std::this_thread::yield}}
whether this replacement occurs on freestanding implementations.
\begin{note}
In a freestanding environment,
concurrent forward progress is not guaranteed;
such systems therefore require explicit cooperation.
A call to yield can add implicit cooperation where none is otherwise intended.
\end{note}

\rSec2[stmt.while]{The \keyword{while} statement}%
\indextext{statement!\idxcode{while}}

\pnum
In the \keyword{while} statement, the substatement is executed repeatedly
until the value of the condition\iref{stmt.pre} becomes
\tcode{false}. The test takes place before each execution of the
substatement.

\pnum
\indextext{statement!declaration in \tcode{while}}%
A \keyword{while} statement is equivalent to
\begin{ncsimplebnf}
\exposid{label} \terminal{:}\br
\terminal{\{}\br
\bnfindent \keyword{if} \terminal{(} condition \terminal{)} \terminal{\{}\br
\bnfindent \bnfindent statement\br
\bnfindent \bnfindent \keyword{goto} \exposid{label} \terminal{;}\br
\bnfindent \terminal{\}}\br
\terminal{\}}
\end{ncsimplebnf}
\begin{note}
The variable created in the condition is destroyed and created with each
iteration of the loop.
\begin{example}
\begin{codeblock}
struct A {
  int val;
  A(int i) : val(i) { }
  ~A() { }
  operator bool() { return val != 0; }
};
int i = 1;
while (A a = i) {
  // ...
  i = 0;
}
\end{codeblock}
In the while-loop, the constructor and destructor are each called twice,
once for the condition that succeeds and once for the condition that
fails.
\end{example}
\end{note}

\rSec2[stmt.do]{The \keyword{do} statement}%
\indextext{statement!\idxcode{do}}

\pnum
The expression is contextually converted to \tcode{bool}\iref{conv};
if that conversion is ill-formed, the program is ill-formed.

\pnum
In the \keyword{do} statement, the substatement is executed repeatedly
until the value of the expression becomes \tcode{false}. The test takes
place after each execution of the statement.

\rSec2[stmt.for]{The \tcode{for} statement}%
\indextext{statement!\idxcode{for}}

\pnum
The \keyword{for} statement
\begin{ncsimplebnf}
\keyword{for} \terminal{(} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement
\end{ncsimplebnf}
is equivalent to
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent init-statement\br
\bnfindent \keyword{while} \terminal{(} condition \terminal{)} \terminal{\{}\br
\bnfindent\bnfindent statement\br
\bnfindent\bnfindent expression \terminal{;}\br
\bnfindent \terminal{\}}\br
\terminal{\}}
\end{ncsimplebnf}
except that the \grammarterm{init-statement} is
in the same scope as the \grammarterm{condition}, and
except that a
\indextext{statement!\tcode{continue} in \tcode{for}}%
\keyword{continue} in \grammarterm{statement} (not enclosed in another
iteration statement) will execute \grammarterm{expression} before
re-evaluating \grammarterm{condition}.
\begin{note}
Thus the first statement specifies initialization for the loop; the
condition\iref{stmt.pre} specifies a test, sequenced before each
iteration, such that the loop is exited when the condition becomes
\tcode{false}; the expression often specifies incrementing that is
sequenced after each iteration.
\end{note}

\pnum
Either or both of the \grammarterm{condition}
and the \grammarterm{expression} can be omitted.
A missing \grammarterm{condition}
makes the implied \keyword{while} clause
equivalent to \tcode{while (true)}.

\rSec2[stmt.ranged]{The range-based \keyword{for} statement}%
\indextext{statement!range based for@range based \tcode{for}}

\pnum
The range-based \keyword{for} statement
\begin{ncsimplebnf}
\keyword{for} \terminal{(} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement
\end{ncsimplebnf}
is equivalent to
\begin{ncsimplebnf}
\terminal{\{}\br
\bnfindent \opt{init-statement}\br
\bnfindent \keyword{auto} \terminal{\&\&}\exposid{range} \terminal{=} for-range-initializer \terminal{;}\br
\bnfindent \keyword{auto} \exposid{begin} \terminal{=} \exposid{begin-expr} \terminal{;}\br
\bnfindent \keyword{auto} \exposid{end} \terminal{=} \exposid{end-expr} \terminal{;}\br
\bnfindent \keyword{for} \terminal{(} \terminal{;} \exposid{begin} \terminal{!=} \exposid{end}\terminal{;} \terminal{++}\exposid{begin} \terminal{)} \terminal{\{}\br
\bnfindent\bnfindent for-range-declaration \terminal{=} \terminal{*} \exposid{begin} \terminal{;}\br
\bnfindent\bnfindent statement\br
\bnfindent \terminal{\}}\br
\terminal{\}}
\end{ncsimplebnf}
where
\begin{itemize}
\item
if the \grammarterm{for-range-initializer} is an \grammarterm{expression},
it is regarded as if it were surrounded by parentheses (so that a comma operator
cannot be reinterpreted as delimiting two \grammarterm{init-declarator}{s});

\item \exposid{range}, \exposid{begin}, and \exposid{end} are variables defined for
exposition only; and

\item
\exposid{begin-expr} and \exposid{end-expr} are determined as follows:

\begin{itemize}
\item if the type of \exposid{range} is a reference to an
array type \tcode{R}, \exposid{begin-expr} and \exposid{end-expr} are
\exposid{range} and \exposid{range} \tcode{+} \tcode{N}, respectively,
where \tcode{N} is
the array bound. If \tcode{R} is an array of unknown bound or an array of
incomplete type, the program is ill-formed;

\item if the type of \exposid{range} is a reference to a
class type \tcode{C}, and
searches in the scope of \tcode{C}\iref{class.member.lookup}
for the names \tcode{begin} and \tcode{end}
each find at least one declaration,
\exposid{begin-expr} and \exposid{end-expr} are
\tcode{\exposid{range}.begin()} and \tcode{\exposid{range}.end()},
respectively;

\item otherwise, \exposid{begin-expr} and \exposid{end-expr} are
\tcode{begin(\exposid{range})} and \tcode{end(\exposid{range})}, respectively,
where \tcode{begin} and \tcode{end} undergo
argument-dependent lookup\iref{basic.lookup.argdep}.
\begin{note}
Ordinary unqualified lookup\iref{basic.lookup.unqual} is not
performed.
\end{note}
\end{itemize}
\end{itemize}
\begin{example}
\begin{codeblock}
int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
  x *= 2;
\end{codeblock}
\end{example}
\begin{note}
The lifetime of some temporaries in the \grammarterm{for-range-initializer}
is extended to cover the entire loop\iref{class.temporary}.
\end{note}
\begin{example}
\begin{codeblock}
using T = std::list<int>;
const T& f1(const T& t) { return t; }
const T& f2(T t)        { return t; }
T g();

void foo() {
  for (auto e : f1(g())) {}     // OK, lifetime of return value of \tcode{g()} extended
  for (auto e : f2(g())) {}     // undefined behavior
}
\end{codeblock}
\end{example}

\indextext{statement!iteration|)}

\rSec1[stmt.expand]{Expansion statements}
\indextext{statement!expansion|(}

\pnum
Expansion statements specify repeated instantiations\iref{temp.decls.general}
of their substatement.

\begin{bnf}
\nontermdef{expansion-statement}\br
    \keyword{template} \keyword{for} \terminal{(}
        \opt{init-statement} for-range-declaration \terminal{:}
        expansion-initializer \terminal{)} compound-statement
\end{bnf}

\begin{bnf}
\nontermdef{expansion-initializer}\br
    expression\br
    expansion-init-list
\end{bnf}

\begin{bnf}
\nontermdef{expansion-init-list}\br
    \terminal{\{} expression-list \opt{\terminal{,}} \terminal{\}}\br
    \terminal{\{} \terminal{\}}
\end{bnf}

\pnum
The \grammarterm{compound-statement} of an \grammarterm{expansion-statement}
is a control-flow-limited statement\iref{stmt.label}.

\pnum
For an expression \tcode{E}, let the expressions
\exposid{begin-expr} and \exposid{end-expr} be determined as specified in~\ref{stmt.ranged}.
An expression is \defn{expansion-iterable} if it does not have array type and either
\begin{itemize}
\item
\exposid{begin-expr} and \exposid{end-expr} are of the form
\tcode{E.begin()} and \tcode{E.end()}, or
\item
argument-dependent lookups for \tcode{begin(E)} and for \tcode{end(E)}
each find at least one viable candidate\iref{over.match.viable}.
\end{itemize}

\pnum
An expansion statement is
\begin{itemize}
\item
an \defnadj{enumerating}{expansion statement} if its \grammarterm{expansion-initializer}
is of the form \grammarterm{expansion-init-list};
\item
otherwise, an \defnadj{iterating}{expansion statement} if its \grammarterm{expansion-initializer}
is an expansion-iterable expression;
\item
otherwise, a \defnadj{destructuring}{expansion statement}.
\end{itemize}

\pnum
An expansion statement $S$ is equivalent to a \grammarterm{compound-statement}
containing instantiations of the \grammarterm{for-range-declaration}
(including its implied initialization),
together with the compound-statement of $S$, as follows:
\begin{itemize}
\item
If $S$ is an enumerating expansion statement, $S$ is equivalent to:
\begin{codeblock}
{
  @\grammarterm{init-statement}@
  @$S_{0}$@
  @\vdots@
  @$S_{N-1}$@
}
\end{codeblock}
where $N$ is the number of elements in the \grammarterm{expression-list},
$S_{i}$ is
\begin{codeblock}
{
  @\grammarterm{for-range-declaration}@ = @$E_{i}$@;
  @\grammarterm{compound-statement}@
}
\end{codeblock}
and $E_{i}$ is the $i^{\text{th}}$ element of the \grammarterm{expression-list}.

\item
Otherwise, if $S$ is an iterating expansion statement, $S$ is equivalent to:
\begin{codeblock}
{
  @\grammarterm{init-statement}@
  @\opt{constexpr}@ decltype(auto) @\exposidnc{range}@ = (@\grammarterm{expansion-initializer}@);
  @\opt{constexpr}@ auto @\exposidnc{begin}@ = @\exposidnc{begin-expr}@;         // see \ref{stmt.ranged}
  @$S_{0}$@
  @\vdots@
  @$S_{N-1}$@
}
\end{codeblock}
where $N$ is the result of evaluating the expression
\begin{codeblock}
[&] consteval {
  std::ptrdiff_t result = 0;
  auto b = @\exposid{begin-expr}@;
  auto e = @\exposid{end-expr}@;
  for (; b != e; ++b) ++result;
  return result;                                // distance from \exposid{begin} to \exposid{end}
}()
\end{codeblock}
and $S_{i}$ is
\begin{codeblock}
{
  @\opt{constexpr}@ auto @\exposid{iter}@ = @\exposid{begin}@ + decltype(begin - begin){@\placeholder{i}@};
  @\grammarterm{for-range-declaration}@ = *@\exposid{iter}@;
  @\grammarterm{compound-statement}@
}
\end{codeblock}
The variables \exposid{range}, \exposid{begin}, and \exposid{iter}
are defined for exposition only.
The keyword \keyword{constexpr} is present in the declarations
of \exposid{range}, \exposid{begin}, and \exposid{iter}
if and only if
\keyword{constexpr} is one of the \grammarterm{decl-specifier}{s} of
the \grammarterm{decl-specifier-seq} of
the \grammarterm{for-range-declaration}.
The identifier \tcode{\placeholder{i}} is considered to be
a prvalue of type \tcode{std::ptrdiff_t};
the program is ill-formed if
\tcode{\placeholder{i}} is not representable as such a value.

\item
Otherwise, $S$ is a destructuring expansion statement and,
if $N$ is $0$, $S$ is equivalent to:
\begin{codeblock}
{
  @\grammarterm{init-statement}@
  @\opt{\keyword{constexpr}}@ auto&& @\exposid{range}@ = @\grammarterm{expansion-initializer}@;
}
\end{codeblock}
otherwise, $S$ is equivalent to:
\begin{codeblock}
{
  @\grammarterm{init-statement}@
  @\opt{\keyword{constexpr}}@ auto&& [@$u_{0}$@, @$u_{1}$@, @$\dotsc$@, @$u_{N-1}$@] = @\grammarterm{expansion-initializer}@;
  @$S_{0}$@
  @\vdots@
  @$S_{N-1}$@
}
\end{codeblock}
where $N$ is the structured binding size of the type
of the \grammarterm{expansion-initializer} and $S_{i}$ is
\begin{codeblock}
{
  @\grammarterm{for-range-declaration}@ = @$v_{i}$@;
  @\grammarterm{compound-statement}@
}
\end{codeblock}
If the \grammarterm{expansion-initializer} is an lvalue, then
$v_{i}$ is $u_{i}$;
otherwise, $v_{i}$ is \tcode{static_cast<decltype($u_{i}$)\&\&>($u_{i}$)}.
The keyword \keyword{constexpr} is present in the \grammarterm{structured-binding-declaration}
of $u_{0}, u_{1}, \dotsc, u_{N-1}$ if and only if
\keyword{constexpr} is one of the \grammarterm{decl-specifier}s
of the \grammarterm{decl-specifier-seq}
of the \grammarterm{for-range-declaration}.
\end{itemize}

\pnum
\begin{example}
\begin{codeblock}
consteval int f(auto const&... Containers) {
  int result = 0;
  template for (auto const& c : {Containers...}) {      // OK, enumerating expansion statement
    result += c[0];
  }
  return result;
}
constexpr int c1[] = {1, 2, 3};
constexpr int c2[] = {4, 3, 2, 1};
static_assert(f(c1, c2) == 5);
\end{codeblock}
\end{example}

\pnum
\begin{example}
\begin{codeblock}
consteval int f() {
  constexpr std::array<int, 3> arr {1, 2, 3};
  int result = 0;
  template for (constexpr int s : arr) {                // OK, iterating expansion statement
    result += sizeof(char[s]);
  }
  return result;
}
static_assert(f() == 6);
\end{codeblock}
\end{example}

\pnum
\begin{example}
\begin{codeblock}
struct S {
  int i;
  short s;
};

consteval long f(S s) {
  long result = 0;
  template for (auto x : s) {                           // OK, destructuring expansion statement
    result += sizeof(x);
  }
  return result;
}
static_assert(f(S{}) == sizeof(int) + sizeof(short));
\end{codeblock}
\end{example}

\indextext{statement!expansion|)}

\rSec1[stmt.jump]{Jump statements}%

\rSec2[stmt.jump.general]{General}%
\indextext{statement!jump}

\pnum
Jump statements unconditionally transfer control.
\indextext{statement!jump}%

\indextext{statement!\idxcode{break}}%
\indextext{statement!\idxcode{continue}}%
\indextext{return statement@\tcode{return} statement|see{\tcode{return}}}%
\indextext{\idxcode{return}}%
\indextext{statement!\idxcode{goto}}%
%
\begin{bnf}
\nontermdef{jump-statement}\br
    \keyword{break} \terminal{;}\br
    \keyword{continue} \terminal{;}\br
    \keyword{return} \opt{expr-or-braced-init-list} \terminal{;}\br
    coroutine-return-statement\br
    \keyword{goto} identifier \terminal{;}
\end{bnf}

\pnum
\indextext{local variable!destruction of}%
\indextext{scope!destructor and exit from}%
\begin{note}
On exit from a scope (however accomplished), objects with automatic storage
duration\iref{basic.stc.auto} that have been constructed in that scope are destroyed
in the reverse order of their construction\iref{stmt.dcl}.
For temporaries, see~\ref{class.temporary}.
However, the program can be terminated (by calling
\indextext{\idxcode{exit}}%
\indexlibraryglobal{exit}%
\tcode{std::exit()} or
\indextext{\idxcode{abort}}%
\indexlibraryglobal{abort}%
\tcode{std::abort()}\iref{support.start.term}, for example) without
destroying objects with automatic storage duration.
\end{note}
\begin{note}
A suspension of a coroutine\iref{expr.await} is not considered to be an exit from a scope.
\end{note}

\rSec2[stmt.break]{The \keyword{break} statement}%
\indextext{statement!\idxcode{break}}

\pnum
A \keyword{break} statement shall be enclosed by\iref{stmt.pre}
\indextext{\idxgram{iteration-statement}}%
\indextext{statement!\idxcode{switch}}%
an \grammarterm{iteration-statement}\iref{stmt.iter},
an \grammarterm{expansion-statement}\iref{stmt.expand}, or
a \keyword{switch} statement\iref{stmt.switch}.
The \keyword{break} statement causes
termination of the innermost such enclosing statement;
control passes to the statement following the
terminated statement, if any.

\rSec2[stmt.cont]{The \keyword{continue} statement}%
\indextext{statement!\idxcode{continue}}

\pnum
A \keyword{continue}
statement shall be enclosed by\iref{stmt.pre}
\indextext{\idxgram{iteration-statement}}%
an \grammarterm{iteration-statement} or an \grammarterm{expansion-statement}.
If the innermost enclosing such statement $X$
is an \grammarterm{iteration-statement}\iref{stmt.iter},
the \keyword{continue} statement
causes control to pass to the end of the \grammarterm{statement} of $X$.
Otherwise, control passes to the end of the \grammarterm{compound-statement}
of the current $S_{i}$\iref{stmt.expand}.

\rSec2[stmt.return]{The \keyword{return} statement}%
\indextext{\idxcode{return}}%
\indextext{function return|see{\tcode{return}}}%

\pnum
A function returns control to its caller by the \tcode{return} statement.

\pnum
The \grammarterm{expr-or-braced-init-list}
of a \tcode{return} statement is called its operand. A \tcode{return} statement with
no operand shall be used only in a function whose return type is
\cv{}~\keyword{void}, a constructor\iref{class.ctor}, or a
destructor\iref{class.dtor}.
\indextext{\idxcode{return}!constructor and}%
\indextext{\idxcode{return}!constructor and}%
A \tcode{return} statement with an operand of type \keyword{void} shall be used only
in a function that has a \cv{}~\keyword{void} return type.
A \tcode{return} statement with any other operand shall be used only
in a function that has a return type other than \cv{}~\keyword{void};
\indextext{conversion!return type}%
the \tcode{return} statement initializes the
returned reference or prvalue result object
of the (explicit or implicit) function call
by copy-initialization\iref{dcl.init} from the operand.
\begin{note}
A constructor or destructor does not have a return type.
\end{note}
\begin{note}
A \tcode{return} statement can involve
an invocation of a constructor to perform a copy or move of the operand
if it is not a prvalue or if its type differs from the return type of the function.
A copy operation associated with a \tcode{return} statement can be elided or
converted to a move operation if an automatic storage duration variable is returned\iref{class.copy.elision}.
\end{note}

\pnum
The destructor for the result object
is potentially invoked\iref{class.dtor,except.ctor}.
\begin{example}
\begin{codeblock}
class A {
  ~A() {}
};
A f() { return A(); }   // error: destructor of \tcode{A} is private (even though it is never invoked)
\end{codeblock}
\end{example}

\pnum
Flowing off the end of
a constructor,
a destructor, or
a non-coroutine function with a \cv{}~\keyword{void} return type is
equivalent to a \tcode{return} with no operand.
Otherwise, flowing off the end of a function
that is neither \tcode{main}\iref{basic.start.main} nor a coroutine\iref{dcl.fct.def.coroutine}
results in undefined behavior.

\pnum
The copy-initialization of the result of the call is sequenced before the
destruction of temporaries at the end of the full-expression established
by the operand of the \tcode{return} statement, which, in turn, is sequenced
before the destruction of local variables\iref{stmt.jump} of the block
enclosing the \tcode{return} statement.
\begin{note}
These operations
are sequenced before the destruction of local variables
in each remaining enclosing block of the function\iref{stmt.dcl},
which, in turn,
is sequenced before the evaluation of
postcondition assertions of the function\iref{dcl.contract.func},
which, in turn,
is sequenced before the destruction of function parameters\iref{expr.call}.
\end{note}

\pnum
In a function
other than an invented function for \tcode{std::is_convertible}\iref{meta.rel},
a \tcode{return} statement that binds
\begin{itemize}
\item a returned reference or
\item a constituent reference\iref{intro.object} of a returned object
\end{itemize}
to a temporary expression\iref{class.temporary} is ill-formed.
\begin{example}
\begin{codeblock}
auto&& f1() {
  return 42;            // ill-formed
}
const double& f2() {
  static int x = 42;
  return x;             // ill-formed
}
auto&& id(auto&& r) {
  return static_cast<decltype(r)&&>(r);
}
auto&& f3() {
  return id(42);        // OK, but probably a bug
}
\end{codeblock}
\end{example}

\rSec2[stmt.return.coroutine]{The \keyword{co_return} statement}%
\indextext{\idxcode{co_return}}%
\indextext{coroutine return|see{\tcode{co_return}}}%

\begin{bnf}
\nontermdef{coroutine-return-statement}\br
    \keyword{co_return} \opt{expr-or-braced-init-list} \terminal{;}
\end{bnf}

\pnum
A \keyword{co_return} statement transfers control to
the caller or resumer of a coroutine\iref{dcl.fct.def.coroutine}.
A coroutine shall not enclose
a \tcode{return} statement\iref{stmt.return}.
\begin{note}
For this determination, it is irrelevant whether the \tcode{return} statement
is enclosed by a discarded statement\iref{stmt.if}.
\end{note}

\pnum
The \grammarterm{expr-or-braced-init-list} of a \keyword{co_return} statement is
called its operand.
Let \placeholder{p} be an lvalue naming the coroutine
promise object\iref{dcl.fct.def.coroutine}.
A \keyword{co_return} statement is equivalent to:
\begin{ncsimplebnf}
\terminal{\{} S\terminal{;} \keyword{goto} \exposid{final-suspend}\terminal{;} \terminal{\}}
\end{ncsimplebnf}
where \exposid{final-suspend} is the exposition-only label
defined in \ref{dcl.fct.def.coroutine}
and \placeholder{S} is defined as follows:
\begin{itemize}
\item
If the operand is a \grammarterm{braced-init-list} or an expression of non-\keyword{void} type,
\placeholder{S} is \placeholder{p}\tcode{.return_value(}\grammarterm{expr-or-braced-init-list}{}\tcode{)}.
The expression \placeholder{S} shall be a prvalue of type \keyword{void}.

\item
Otherwise,
\placeholder{S} is the \grammarterm{compound-statement} \tcode{\{}{ }\opt{\grammarterm{expression}} \tcode{;} \placeholder{p}\tcode{.return_void()}\tcode{;{ }\}}.
The expression \placeholder{p}\tcode{.return_void()}
shall be a prvalue of type \keyword{void}.
\end{itemize}

\pnum
If a search for the name \tcode{return_void} in the scope of the promise type
finds any declarations,
flowing off the end of a coroutine's \grammarterm{function-body}
is equivalent to a \keyword{co_return} with no operand;
otherwise flowing off the end of a coroutine's \grammarterm{function-body}
results in undefined behavior.

\rSec2[stmt.goto]{The \keyword{goto} statement}%
\indextext{statement!\idxcode{goto}}

\pnum
The \tcode{goto} statement unconditionally transfers control to the
statement labeled by the identifier. The identifier shall be a
\indextext{label}%
label\iref{stmt.label} located in the current function.

\rSec1[stmt.contract.assert]{Assertion statement}

\begin{bnf}
\nontermdef{assertion-statement}\br
    \terminal{contract_assert} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)} \terminal{;}
\end{bnf}

\pnum
\indexdefn{contract assertion!statement|see{assertion, statement}}
\indextext{assertion!statement}
An \grammarterm{assertion-statement}
introduces a contract assertion\iref{basic.contract}.
The optional \grammarterm{attribute-specifier-seq}
appertains to the introduced contract assertion.

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

\pnum
The evaluation of consecutive \grammarterm{assertion-statement}s
is an evaluation in sequence\iref{basic.contract.eval} of
the contract assertions introduced
by those \grammarterm{assertion-statement}s.
\begin{note}
A sequence of \grammarterm{assertion-statement}s
can thus be repeatedly evaluated as a group.
\begin{example}
\begin{codeblock}
int f(int i)
{
  contract_assert(i == 0);  // \#1
  contract_assert(i >= 0);  // \#2
  return 0;
}
int g = f(0);   // can evaluate \#1, \#2, \#1, \#2
\end{codeblock}
\end{example}
\end{note}

\rSec1[stmt.dcl]{Declaration statement}%
\indextext{statement!declaration}

\pnum
A declaration statement introduces one or more new names into a
block; it has the form
\begin{bnf}
\nontermdef{declaration-statement}\br
    block-declaration
\end{bnf}
\begin{note}
If an identifier introduced by a declaration was previously declared in
an outer block,
\indextext{declaration hiding|see{name hiding}}%
\indextext{name hiding}%
\indextext{block (statement)!structure}%
the outer declaration is hidden
for the remainder of the block\iref{basic.lookup.unqual},
after which it resumes its force.
\end{note}

\pnum
\indextext{block (statement)!initialization in}%
\indextext{initialization!automatic}%
\indextext{active|see{variable, active}}%
A block variable with automatic storage duration\iref{basic.stc.auto}
is \defnx{active}{variable!active} everywhere in the scope to which it belongs
after its \grammarterm{init-declarator}.
\indextext{initialization!jump past}%
\indextext{\idxcode{goto}!initialization and}%
Upon each transfer of control (including sequential execution of statements,
but excluding function calls)
within a function from point $P$ to point $Q$,
all block variables with automatic storage duration
that are active at $P$ and not at $Q$ are destroyed in the reverse order of their construction.
Then, all block variables with automatic storage duration
that are active at $Q$ but not at $P$ are initialized in declaration order;
unless all such variables have vacuous initialization\iref{basic.life},
the transfer of control shall not be a jump.
\begin{footnote}
The transfer from the condition of a \keyword{switch} statement to a
\keyword{case} label is considered a jump in this respect.
\end{footnote}
When a \grammarterm{declaration-statement} is executed,
$P$ and $Q$ are the points immediately before and after it;
when a function returns, $Q$ is after its body.
\begin{example}
\begin{codeblock}
void f() {
  // ...
  goto lx;          // error: jump into scope of \tcode{a}
  // ...
ly:
  X a = 1;
  // ...
lx:
  goto ly;          // OK, jump implies destructor call for \tcode{a} followed by
                    // construction again immediately following label \tcode{ly}
}
\end{codeblock}
\end{example}

\pnum
\indextext{initialization!automatic}%
\indextext{initialization!dynamic block-scope}%
\indextext{initialization!local \tcode{static}}%
\indextext{initialization!local \tcode{thread_local}}%
Dynamic initialization of a block variable with
static storage duration\iref{basic.stc.static} or
thread storage duration\iref{basic.stc.thread} is performed
the first time control passes through its declaration; such a variable is
considered initialized upon the completion of its initialization. If the
initialization exits by throwing an exception, the initialization is not
complete, so it will be tried again the next time control enters the
declaration.
If control enters the declaration concurrently while the variable is
being initialized, the concurrent execution shall wait for completion
of the initialization.
\begin{note}
A conforming implementation cannot introduce
any deadlock around execution of the initializer.
Deadlocks might still be caused by the program logic;
the implementation need only avoid deadlocks
due to its own synchronization operations.
\end{note}
If control
re-enters the declaration recursively while
the variable is being initialized, the behavior is undefined.
\begin{example}
\begin{codeblock}
int foo(int i) {
  static int s = foo(2*i);      // undefined behavior: recursive call
  return i+1;
}
\end{codeblock}
\end{example}

\pnum
\indextext{\idxcode{static}!destruction of local}%
An object associated with
a block variable with static or thread storage duration
will be destroyed if and only if it was constructed.
\begin{note}
\ref{basic.start.term} describes the order in which such objects are destroyed.
\end{note}

\rSec1[stmt.ambig]{Ambiguity resolution}%
\indextext{ambiguity!declaration versus expression}

\pnum
There is an ambiguity in the grammar involving
\grammarterm{expression-statement}{s} and \grammarterm{declaration}{s}: An
\grammarterm{expression-statement} with a function-style explicit type
conversion\iref{expr.type.conv} as its leftmost subexpression can be
indistinguishable from a \grammarterm{declaration} where the first
\grammarterm{declarator} starts with a \tcode{(}. In those cases the
\grammarterm{statement} is considered a \grammarterm{declaration},
except as specified below.

\pnum
\begin{note}
If the \grammarterm{statement} cannot syntactically be a
\grammarterm{declaration}, there is no ambiguity,
so this rule does not apply.
In some cases, the whole \grammarterm{statement} needs to be examined
to determine whether this is the case. This resolves the meaning
of many examples.
\begin{example}
Assuming \tcode{T} is a
\grammarterm{simple-type-specifier}\iref{dcl.type.simple},

\begin{codeblock}
T(a)->m = 7;        // expression-statement
T(a)++;             // expression-statement
T(a,5)<<c;          // expression-statement

T(*d)(int);         //  declaration
T(e)[5];            //  declaration
T(f) = { 1, 2 };    //  declaration
T(*g)(double(3));   //  declaration
\end{codeblock}

In the last example above, \tcode{g}, which is a pointer to \tcode{T},
is initialized to \tcode{double(3)}. This is of course ill-formed for
semantic reasons, but that does not affect the syntactic analysis.
\end{example}

The remaining cases are \grammarterm{declaration}{s}.
\begin{example}
\begin{codeblock}
class T {
  // ...
public:
  T();
  T(int);
  T(int, int);
};
T(a);               //  declaration
T(*b)();            //  declaration
T(c)=7;             //  declaration
T(d),e,f=3;         //  declaration
extern int h;
T(g)(h,2);          //  declaration
\end{codeblock}
\end{example}
\end{note}

\pnum
The disambiguation is purely syntactic; that is, the meaning of the
names occurring in such a statement, beyond whether they are
\grammarterm{type-name}{s} or not, is not generally used in or changed by the
disambiguation. Class templates are instantiated as necessary to
determine if a qualified name is a \grammarterm{type-name}. Disambiguation
precedes parsing, and a statement disambiguated as a declaration may be
an ill-formed declaration.
If, during parsing, lookup finds
that a name in a template argument is bound to
(part of) the declaration being parsed,
the program is ill-formed.
No diagnostic is required.
\begin{example}
\begin{codeblock}
struct T1 {
  T1 operator()(int x) { return T1(x); }
  int operator=(int x) { return x; }
  T1(int) { }
};
struct T2 { T2(int) { } };
int a, (*(*b)(T2))(int), c, d;

void f() {
  // disambiguation requires this to be parsed as a declaration:
  T1(a) = 3,
  T2(4),                        // \tcode{T2} will be declared as a variable of type \tcode{T1}, but this will not
  (*(*b)(T2(c)))(int(d));       // allow the last part of the declaration to parse properly,
                                // since it depends on \tcode{T2} being a \grammarterm{type-name}
}
\end{codeblock}
\end{example}

\pnum
A syntactically ambiguous statement that can syntactically be
a \grammarterm{declaration} with an outermost \grammarterm{declarator}
with a \grammarterm{trailing-return-type}
is considered a \grammarterm{declaration} only if it starts with \keyword{auto}.
\begin{example}
\begin{codeblock}
struct M;
struct S {
  S* operator()();
  int N;
  int M;

  void mem(S s) {
    auto(s)()->M;               // expression, \tcode{S::M} hides \tcode{::M}
  }
};

void f(S s) {
  {
    auto(s)()->N;               // expression
    auto(s)()->M;               // function declaration
  }
  {
    S(s)()->N;                  // expression
    S(s)()->M;                  // expression
  }
}
\end{codeblock}
\end{example}
\indextext{statement|)}
