8 Statements [stmt.stmt]

8.6 Iteration statements [stmt.iter]

8.6.1 General [stmt.iter.general]

The substatement in an iteration-statement implicitly defines a block scope which is entered and exited each time through the loop.
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 1:
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.
— end example]
If a name introduced in an init-statement or for-range-declaration is redeclared in the outermost block of the substatement, the program is ill-formed.
[Example 2: void f() { for (int i = 0; i < 10; ++i) int i = 0; // error: redeclaration for (int i : { 1, 2, 3 }) int i = 1; // error: redeclaration } — end example]

8.6.2 The while statement [stmt.while]

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.
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 is equivalent to
label :
{
   if ( condition ) {
      statement
      goto label ;
   }
}
[Note 1:
The variable created in the condition is destroyed and created with each iteration of the loop.
[Example 1: 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.
— end example]
— end note]

8.6.3 The do statement [stmt.do]

The expression is contextually converted to bool; if that conversion is ill-formed, the program is ill-formed.
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.

8.6.4 The for statement [stmt.for]

The for statement is equivalent to
{
   init-statement
   while ( condition ) {
      statement
      expression ;
   }
}
except that names declared in the 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 1:
Thus the first statement specifies initialization for the loop; the condition ([stmt.select]) specifies a test, sequenced before each iteration, such that the loop is exited when the condition becomes false; the expression often specifies incrementing that is sequenced after each iteration.
— end note]
Either or both of the condition and the expression can be omitted.
A missing condition makes the implied while clause equivalent to while(true).
If the init-statement is a declaration, the scope of the name(s) declared extends to the end of the for statement.
[Example 1: int i = 42; int a[10]; for (int i = 0; i < 10; i++) a[i] = i; int j = i; // j = 42 — end example]

8.6.5 The range-based for statement [stmt.ranged]

The range-based for statement is equivalent to
{
   init-statement
   auto &&range = for-range-initializer ;
   auto begin = begin-expr ;
   auto end = end-expr ;
   for ( ; begin != end; ++begin ) {
      for-range-declaration = * begin ;
      statement
   }
}
where
  • if the for-range-initializer is an expression, it is regarded as if it were surrounded by parentheses (so that a comma operator cannot be reinterpreted as delimiting two init-declarators);
  • range, begin, and end are variables defined for exposition only; and
  • begin-expr and end-expr are determined as follows:
    • if the for-range-initializer is an expression of array type R, begin-expr and end-expr are range and range + N, respectively, where N is the array bound.
      If R is an array of unknown bound or an array of incomplete type, the program is ill-formed;
    • if the for-range-initializer is an expression of class type C, the unqualified-ids begin and end are looked up in the scope of C as if by class member access lookup ([basic.lookup.classref]), and if both find at least one declaration, begin-expr and end-expr are range.begin() and range.end(), respectively;
    • otherwise, begin-expr and end-expr are begin(range) and end(range), respectively, where begin and end are looked up in the associated namespaces ([basic.lookup.argdep]).
      [Note 1:
      Ordinary unqualified lookup ([basic.lookup.unqual]) is not performed.
      — end note]
[Example 1: int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2; — end example]
In the decl-specifier-seq of a for-range-declaration, each decl-specifier shall be either a type-specifier or constexpr.
The decl-specifier-seq shall not define a class or enumeration.