______________________________________________________________________
6 Statements [stmt.stmt]
______________________________________________________________________
1 Except as indicated, statements are executed in sequence.
statement:
labeled-statement
expression-statement
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
6.1 Labeled statement [stmt.label]
1 A statement can be labeled.
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
An identifier label declares the identifier. The only use of an iden-
tifier label is as the target of a goto. The scope of a label is the
function in which it appears. Labels shall not be redeclared within a
function. A label can be used in a goto statement before its defini-
tion. Labels have their own name space and do not interfere with
other identifiers.
2 Case labels and default labels shall occur only in switch statements.
6.2 Expression statement [stmt.expr]
1 Expression statements have the form
expression-statement:
expressionopt ;
The expression is evaluated and its value is discarded. The lvalue-to-
rvalue (_conv.lval_), array-to-pointer (_conv.array_), and function-
to-pointer (_conv.func_) standard conversions are not applied to the
expression. All side effects from an expression statement are com-
pleted before the next statement is executed. An expression statement
with the expression missing is called a null statement. [Note: Most
statements are expression statements--usually assignments or function
calls. A null statement is useful to carry a label just before the }
of a compound statement and to supply a null body to an iteration
statement such as a while statement (_stmt.while_). ]
6.3 Compound statement or block [stmt.block]
1 So that several statements can be used where one is expected, the com-
pound statement (also, and equivalently, called "block") is provided.
compound-statement:
{ statement-seqopt }
statement-seq:
statement
statement-seq statement
A compound statement defines a local scope (_basic.scope_). [Note: a
declaration is a statement (_stmt.dcl_). ]
6.4 Selection statements [stmt.select]
1 Selection statements choose one of several flows of control.
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq declarator = assignment-expression
In this clause, the term substatement refers to the contained state-
ment or statements that appear in the syntax notation. The substate-
ment in a selection-statement (both substatements, in the else form of
the if statement) implicitly defines a local scope (_basic.scope_).
If the substatement in a selection-statement is a single statement and
not a compound-statement, it is as if it was rewritten to be a com-
pound-statement containing the original substatement. [Example:
if (x)
int i;
can be equivalently rewritten as
if (x) {
int i;
}
Thus after the if statement, i is no longer in scope. ]
2 The rules for conditions apply both to selection-statements and to the
for and while statements (_stmt.iter_). The declarator shall not
specify a function or an array. The type-specifier-seq shall not con-
tain typedef and shall not declare a new class or enumeration.
3 A name introduced by a declaration in a condition (either introduced
by the type-specifier-seq or the declarator of the condition) is in
scope from its point of declaration until the end of the substatements
controlled by the condition. If the name is re-declared in the outer-
most block of a substatement controlled by the condition, the declara-
tion that re-declares the name is ill-formed. [Example:
if (int x = f()) {
int x; // ill-formed, redeclaration of 'x'
}
else {
int x; // ill-formed, redeclaration of 'x'
}
--end example]
4 The value of a condition that is an initialized declaration in a
statement other than a switch statement is the value of the declared
variable implicitly converted to type bool. If that conversion is
ill-formed, the program is ill-formed. The value of a condition that
is an initialized declaration in a switch statement is the value of
the declared variable if it has integral or enumeration type, or of
that variable implicitly converted to integral or enumeration type
otherwise. The value of a condition that is an expression is the
value of the expression, implicitly converted to bool for statements
other than 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.
5 If a condition can be syntactically resolved as either an expression
or the declaration of a local name, it is interpreted as a declara-
tion.
6.4.1 The if statement [stmt.if]
1 If the condition (_stmt.select_) yields true the first substatement is
executed. If the else part of the selection statement is present and
the condition yields false, the second substatement is executed. In
the second form of if statement (the one including else), if the first
substatement is also an if statement then that inner if statement
shall contain an else part.1)
6.4.2 The switch statement [stmt.switch]
1 The switch statement causes control to be transferred to one of sev-
eral statements depending on the value of a condition.
2 The condition shall be of integral type, enumeration type, or of a
class type for which a single conversion function to integral or enu-
meration type exists (_class.conv_). If the condition is of class
type, the condition is converted by calling that conversion function,
and the result of the conversion is used in place of the original con-
dition for the remainder of this section. Integral promotions are
performed. Any statement within the switch statement can be labeled
with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be an integral constant-expres-
sion. The integral constant-expression (_expr.const_) is implicitly
converted to the promoted type of the switch condition. No two of the
case constants in the same switch shall have the same value after con-
version to the promoted type of the switch condition.
3 There shall be at most one label of the form
default :
_________________________
1) In other words, the else is associated with the nearest un-elsed
if.
within a switch statement.
4 Switch statements can be nested; a case or default label is associated
with the smallest switch enclosing it.
5 When the switch statement is executed, its condition is evaluated and
compared with each case constant. If one of the case constants is
equal to the value of the condition, control is passed to the state-
ment following the matched case label. If no case constant matches
the condition, and if there is a default label, control passes to the
statement labeled by the default label. If no case matches and if
there is no default then none of the statements in the switch is exe-
cuted.
6 case and default labels in themselves do not alter the flow of con-
trol, which continues unimpeded across such labels. To exit from a
switch, see break, _stmt.break_. [Note: usually, the substatement
that is the subject of a switch is compound and case and default
labels appear on the top-level statements contained within the (com-
pound) substatement, but this is not required. Declarations can
appear in the substatement of a switch-statement. ]
6.5 Iteration statements [stmt.iter]
1 Iteration statements specify looping.
iteration-statement:
while ( condition ) statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ; expressionopt ) statement
for-init-statement:
expression-statement
simple-declaration
[Note: a for-init-statement ends with a semicolon. ]
2 The substatement in an iteration-statement implicitly defines a local
scope (_basic.scope_) which is entered and exited each time through
the loop.
3 If the substatement in an iteration-statement is a single statement
and not a compound-statement, it is as if it was rewritten to be a
compound-statement containing the original statement. [Example:
while (--x >= 0)
int i;
can be equivalently rewritten as
while (--x >= 0) {
int i;
}
Thus after the while statement, i is no longer in scope. ]
4 [Note: The requirements on conditions in iteration statements are
described in _stmt.select_. --end note]
6.5.1 The while statement [stmt.while]
1 In the while statement the substatement is executed repeatedly until
the value of the condition (_stmt.select_) becomes false. The test
takes place before each execution of the substatement.
2 When the condition of a while statement is a declaration, the scope of
the variable that is declared extends from its point of declaration
(_basic.scope.pdecl_) to the end of the while statement. A while
statement of the form
while (T t = x) statement
is equivalent to
label:
{ // start of condition scope
T t = x;
if (t) {
statement
goto label;
}
} // end of condition scope
The object created in a condition is destroyed and created with each
iteration of the loop. [Example:
struct A {
int val;
A(int i) : val(i) { }
~A() { }
operator bool() { return val != 0; }
};
int i = 1;
while (A a = i) {
//...
i = 0;
}
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. ]
6.5.2 The do statement [stmt.do]
1 The expression is implicitly converted to bool; if that is not possi-
ble, the program is ill-formed.
2 In the do statement the substatement is executed repeatedly until the
value of the expression becomes false. The test takes place after
each execution of the statement.
6.5.3 The for statement [stmt.for]
1 The for statement
for ( for-init-statement conditionopt ; expressionopt ) statement
is equivalent to
{
for-init-statement
while ( condition ) {
statement
expression ;
}
}
except that names declared in the for-init-statement are in the same
declarative-region as those declared in the condition, and except that
a continue in statement (not enclosed in another iteration statement)
will execute expression before re-evaluating condition. [Note: Thus
the first statement specifies initialization for the loop; the condi-
tion (_stmt.select_) specifies a test, made before each iteration,
such that the loop is exited when the condition becomes false; the
expression often specifies incrementing that is done after each itera-
tion. ]
2 Either or both of the condition and the expression can be omitted. A
missing condition makes the implied while clause equivalent to
while(true).
3 If the for-init-statement is a declaration, the scope of the name(s)
declared extends to the end of the for-statement. [Example:
int i = 42;
int a[10];
for (int i = 0; i < 10; i++)
a[i] = i;
int j = i; // j = 42
--end example]
6.6 Jump statements [stmt.jump]
1 Jump statements unconditionally transfer control.
jump-statement:
break ;
continue ;
return expressionopt ;
goto identifier ;
2 On exit from a scope (however accomplished), destructors
(_class.dtor_) are called for all constructed objects with automatic
storage duration (_basic.stc.auto_) (named objects or temporaries)
that are declared in that scope, in the reverse order of their decla-
ration. Transfer out of a loop, out of a block, or back past an ini-
tialized variable with automatic storage duration involves the
destruction of variables with automatic storage duration that are in
scope at the point transferred from but not at the point transferred
to. (See _stmt.dcl_ for transfers into blocks). [Note: However, the
program can be terminated (by calling exit() or abort()(_lib.sup-
port.start.term_), for example) without destroying class objects with
automatic storage duration. ]
6.6.1 The break statement [stmt.break]
1 The break statement shall occur only in an iteration-statement or a
switch statement and causes termination of the smallest enclosing
iteration-statement or switch statement; control passes to the state-
ment following the terminated statement, if any.
6.6.2 The continue statement [stmt.cont]
1 The continue statement shall occur only in an iteration-statement and
causes control to pass to the loop-continuation portion of the small-
est enclosing iteration-statement, that is, to the end of the loop.
More precisely, in each of the statements
while (foo) { do { for (;;) {
{ { {
// ... // ... // ...
} } }
contin: ; contin: ; contin: ;
} } while (foo); }
a continue not contained in an enclosed iteration statement is equiva-
lent to goto contin.
6.6.3 The return statement [stmt.return]
1 A function returns to its caller by the return statement.
2 A return statement without an expression can be used only in functions
that do not return a value, that is, a function with the return value
type void, a constructor (_class.ctor_), or a destructor
(_class.dtor_). A return statement with an expression can be used
only in functions returning a value; the value of the expression is
returned to the caller of the function. If required, the expression
is implicitly converted to the return type of the function in which it
appears. A return statement can involve the construction and copy of
a temporary object (_class.temporary_). Flowing off the end of a
function is equivalent to a return with no value; this results in
undefined behavior in a value-returning function.
6.6.4 The goto statement [stmt.goto]
1 The goto statement unconditionally transfers control to the statement
labeled by the identifier. The identifier shall be a label
(_stmt.label_) located in the current function.
6.7 Declaration statement [stmt.dcl]
1 A declaration statement introduces one or more new identifiers into a
block; it has the form
declaration-statement:
block-declaration
If an identifier introduced by a declaration was previously declared
in an outer block, the outer declaration is hidden for the remainder
of the block, after which it resumes its force.
2 Variables with automatic storage duration (_basic.stc.auto_) are ini-
tialized each time their declaration-statement is executed. Variables
with automatic storage duration declared in the block are destroyed on
exit from the block (_stmt.jump_).
3 It is possible to transfer into a block, but not in a way that
bypasses declarations with initialization. A program that jumps2)
from a point where a local variable with automatic storage duration is
not in scope to a point where it is in scope is ill-formed unless the
variable has POD type (_basic.types_) and is declared without an ini-
tializer (_dcl.init_). [Example:
void f()
{
// ...
goto lx; // ill-formed: jump into scope of `a'
// ...
ly:
X a = 1;
// ...
lx:
goto ly; // ok, jump implies destructor
// call for `a' followed by construction
// again immediately following label ly
}
--end example]
4 The zero-initialization (_dcl.init_) of all local objects with static
storage duration (_basic.stc.static_) is performed before any other
initialization takes place. A local object of POD type
(_basic.types_) with static storage duration initialized with con-
stant-expressions is initialized before its block is first entered. An
implementation is permitted to perform early initialization of other
local objects with static storage duration under the same conditions
that an implementation is permitted to statically initialize an object
with static storage duration in namespace scope (_basic.start.init_).
Otherwise such an object is initialized the first time control passes
through its declaration; such an object 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 con-
trol re-enters the declaration (recursively) while the object is being
initialized, the behavior is undefined. [Example:
int foo(int i)
{
static int s = foo(2*i); // recursive call - undefined
return i+1;
}
--end example]
_________________________
2) The transfer from the condition of a switch statement to a case la-
bel is considered a jump in this respect.
5 The destructor for a local object with static storage duration will be
executed if and only if the variable was constructed. [Note:
_basic.start.term_ describes the order in which local objects with
static storage duration are destroyed. ]
6.8 Ambiguity resolution [stmt.ambig]
1 There is an ambiguity in the grammar involving expression-statements
and declarations: An expression-statement with a function-style
explicit type conversion (_expr.type.conv_) as its leftmost subexpres-
sion can be indistinguishable from a declaration where the first
declarator starts with a (. In those cases the statement is a decla-
ration. [Note: To disambiguate, the whole statement might have to be
examined to determine if it is an expression-statement or a declara-
tion. This disambiguates many examples. [Example: assuming T is a
simple-type-specifier (_dcl.type_),
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
In the last example above, g, which is a pointer to T, is initialized
to double(3). This is of course ill-formed for semantic reasons, but
that does not affect the syntactic analysis. --end example]
2 The remaining cases are declarations. [Example:
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 example] --end note]
3 The disambiguation is purely syntactic; that is, the meaning of the
names occurring in such a statement, beyond whether they are type-
names or not, is not generally used in or changed by the disambigua-
tion. Class templates are instantiated as necessary to determine if a
qualified name is a type-name. Disambiguation precedes parsing, and a
statement disambiguated as a declaration may be an ill-formed declara-
tion. If, during parsing, a name in a template parameter is bound
differently than it would be bound during a trial parse, the program
is ill-formed. No diagnostic is required. [Note: This can occur only
when the name is declared earlier in the declaration. ] [Example:
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() {
// dismabiguation requires this to be parsed
// as a declaration
T1(a) = 3,
T2(4), // T2 will be declared as
(*(*b)(T2(c)))(int(d)); // a variable of type T1
// but this will not allow
// the last part of the
// declaration to parse
// properly since it depends
// on T2 being a type-name
}
--end example]