______________________________________________________________________
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 cannot 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 can occur only in switch statements.
6.2 Expression statement [stmt.expr]
1 Most statements are expression statements, which have the form
expression-statement:
expressionopt ;
Usually expression statements are assignments or function calls. All
side effects from an expression statement are completed before the
next statement is executed. An expression statement with the expres
sion missing is called a null statement; it 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 while (_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_).
2 Note that 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
The statement in a selection-statement (both statements, in the else
form of the if statement) implicitly defines a local scope
(_basic.scope_). That is, if the statement in a selection-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 state
ment. For 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 shall not contain
typedef and shall not declare a new class or enumeration.
3 A name introduced by a declaration in a condition is in scope from its
point of declaration until the end of the statements controlled by the
condition. The value of a condition that is an initialized declara
tion is the value of the initialized variable; the value of a condi
tion that is an expression is the value of the expression. The value
of the condition will be referred to as simply the condition where the
usage is unambiguous.
4 A variable, constant, etc. in the outermost block of a statement con
trolled by a condition shall not have the same name as a variable,
constant, etc. declared in the condition.
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 The condition is converted to type bool; if that is not possible, the
program is ill-formed. If it yields true the first substatement is
executed. If else is used and the condition yields false, the second
substatement is executed. The else ambiguity is resolved by connect
ing an else with the last encountered else-less if.
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 or of a class type for which
an unambiguous conversion to integral type exists (_class.conv_).
Integral promotion is performed. Any statement within the statement
can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression (_expr.const_) is converted to the pro
moted type of the switch condition. No two of the case constants in
the same switch shall have the same value.
3 There shall be at most one label of the form
default :
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_.
7 Usually, the statement that is the subject of a switch is compound.
Declarations can appear in the statement 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
declaration-statement
2 Note that a for-init-statement ends with a semicolon.
3 The statement in an iteration-statement implicitly defines a local
scope (_basic.scope_) which is entered and exited each time through
the loop. That is, if the statement 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 state
ment. For 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 See _stmt.select_ for the rules on conditions.
6.5.1 The while statement [stmt.while]
1 In the while statement the substatement is executed repeatedly until
the value of the condition becomes false. The test takes place before
each execution of the statement.
2 The condition is converted to bool (_conv.bool_).
6.5.2 The do statement [stmt.do]
1 In the do statement the substatement is executed repeatedly until the
value of the condition becomes false. The test takes place after each
execution of the statement.
2 The condition is converted to bool (_conv.bool_).
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 a continue in statement (not enclosed in another iteration
statement) will execute expression before re-evaluating condition.
Thus the first statement specifies initialization for the loop; the
condition 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 iteration. The condi
tion is converted to bool (_conv.bool_).
2 Either or both of the condition and the expression can be dropped. 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. For example:
int i = 42;
int a[10];
for (int i = 0; i < 10; i++)
a[i] = i;
int j = i; // j = 42
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). However, the program
can be terminated (by calling exit() or
abort()(_lib.support.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 converted, as in an initialization (_dcl.init_), 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 func
tion.
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:
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 jumps 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 pointer or arithmetic type or is an aggregate
(_dcl.init.aggr_), and is declared without an initializer
(_dcl.init_). For 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
}
4 The default initialization to zero (_dcl.init_) of all local objects
with static storage duration (_basic.stc.static_) is performed before
any other initialization takes place. A local object with static
storage duration (_basic.stc.static_) initialized with a constant-
expression is initialized before its block is first entered. A local
object with static storage duration not initialized with a constant-
expression is initialized the first time control passes completely
through its declaration. If the initialization exits by throwing an
exception, the initialization is not complete, so it will be tried
again the next time the function is called.
5 The destructor for a local object with static storage duration will be
executed if and only if the variable was constructed. The destructor
is called either immediately before or as part of the calls of the
atexit() functions (_lib.support.start.term_). Exactly when is
unspecified.
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.
2 To disambiguate, the whole statement might have to be examined to
determine if it is an expression-statement or a declaration. This
disambiguates many examples. For 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)[]; // 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.
3 The remaining cases are declarations. For example,
T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
T(g)(h,2); // declaration
4 The disambiguation is purely syntactic; that is, the meaning of the
names, beyond whether they are type-ids or not, is not used in the
disambiguation.
5 A slightly different ambiguity between expression-statements and dec
larations is resolved by requiring a type-id for function declarations
within a block (_stmt.block_). For example,
void g()
{
int f(); // declaration
int a; // declaration
f(); // expression-statement
a; // expression-statement
}