9 Statements [stmt.stmt]

9.5 Iteration statements [stmt.iter]

Iteration statements specify looping.
iteration-statement:
	while ( condition ) statement
	do statement while ( expression ) ;
	for ( init-statement condition ; expression ) statement
	for ( for-range-declaration : for-range-initializer ) statement
for-range-declaration:
	attribute-specifier-seq decl-specifier-seq declarator
	attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ]
for-range-initializer:
	expr-or-braced-init-list
[Note
:
An init-statement ends with a semicolon.
end note
]
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
:
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
:
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
]

9.5.1 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 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 variable 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.
end example
]

9.5.2 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.

9.5.3 The for statement [stmt.for]

The for statement
for ( init-statement condition ; expression ) 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
:
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
:
int i = 42;
int a[10];

for (int i = 0; i < 10; i++)
  a[i] = i;

int j = i;          // j = 42
end example
]

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

The range-based for statement
for ( for-range-declaration : for-range-initializer ) statement
is equivalent to
{
	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 + _­_­bound, respectively, where _­_­bound 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, and if either (or both) finds 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.
      [Note
      :
      Ordinary unqualified lookup is not performed.
      end note
      ]
[Example
:
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.