[stmt.iter]

# 8 Statements [[stmt]](./#stmt)

## 8.6 Iteration statements [stmt.iter]

### [8.6.1](#general) General [[stmt.iter.general]](stmt.iter.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L531)

Iteration statements specify looping[.](#general-1.sentence-1)

[iteration-statement:](#nt:iteration-statement "8.6.1 General [stmt.iter.general]")  
while ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
do [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") while ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ;  
for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]")opt ; [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")opt ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") : [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")

[*Note [1](#general-note-1)*:

An [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") ends with a semicolon[.](#general-1.sentence-2)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L550)

The substatement in an [*iteration-statement*](#nt:iteration-statement "8.6.1 General [stmt.iter.general]") implicitly defines
a block [scope](basic.scope "6.4 Scope [basic.scope]") which is entered and exited each time
through the loop[.](#general-2.sentence-1)

If the substatement in an [*iteration-statement*](#nt:iteration-statement "8.6.1 General [stmt.iter.general]") is
a single statement and not a [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]"),
it is as if it was rewritten to be
a [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") containing the original statement[.](#general-2.sentence-2)

[*Example [1](#general-example-1)*:

while (--x >= 0)int i; can be equivalently rewritten aswhile (--x >= 0) {int i;}

Thus after the while statement, i is no longer in scope[.](#general-2.sentence-4)

â *end example*]

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L573)

A [*trivially empty iteration statement*](#def:iteration_statement,trivially_empty "8.6.1 General [stmt.iter.general]") is
an iteration statement matching one of the following forms:

- [(3.1)](#general-3.1)

while ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ;

- [(3.2)](#general-3.2)

while ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) { }

- [(3.3)](#general-3.3)

do ; while ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ;

- [(3.4)](#general-3.4)

do { } while ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ;

- [(3.5)](#general-3.5)

for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")opt ; ) ;

- [(3.6)](#general-3.6)

for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")opt ; ) { }

The [*controlling expression*](#def:expression,controlling "8.6.1 General [stmt.iter.general]") of a trivially empty iteration statement
is the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") of
a while, do, or for statement
(or true, if the for statement has no [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]"))[.](#general-3.sentence-1)

A [*trivial infinite loop*](#def:loop,trivial_infinite "8.6.1 General [stmt.iter.general]") is a trivially empty iteration statement
for which the converted controlling expression is a constant expression,
when interpreted as a [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ([[expr.const]](expr.const "7.7 Constant expressions")), and
evaluates to true[.](#general-3.sentence-2)

The [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") of a trivial infinite loop is replaced with
a call to the function std​::​this_thread​::​yield ([[thread.thread.this]](thread.thread.this "32.4.5 Namespace this_­thread"));
it is implementation-defined
whether this replacement occurs on freestanding implementations[.](#general-3.sentence-3)

[*Note [2](#general-note-2)*:

In a freestanding environment,
concurrent forward progress is not guaranteed;
such systems therefore require explicit cooperation[.](#general-3.sentence-4)

A call to yield can add implicit cooperation where none is otherwise intended[.](#general-3.sentence-5)

â *end note*]

### [8.6.2](#stmt.while) The while statement [[stmt.while]](stmt.while)

[1](#stmt.while-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L607)

In the while statement, the substatement is executed repeatedly
until the value of the condition ([[stmt.pre]](stmt.pre "8.1 Preamble")) becomesfalse[.](#stmt.while-1.sentence-1)

The test takes place before each execution of the
substatement[.](#stmt.while-1.sentence-2)

[2](#stmt.while-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L613)

A while statement is equivalent to

*label* :  
{  
 if ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) {  
 [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
 goto *label* ;  
 }  
}

[*Note [1](#stmt.while-note-1)*:

The variable created in the condition is destroyed and created with each
iteration of the loop[.](#stmt.while-2.sentence-1)

[*Example [1](#stmt.while-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[.](#stmt.while-2.sentence-2)

â *end example*]

â *end note*]

### [8.6.3](#stmt.do) The do statement [[stmt.do]](stmt.do)

[1](#stmt.do-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L651)

The expression is [contextually converted to bool](conv#def:conversion,contextual_to_bool "7.3 Standard conversions [conv]");
if that conversion is ill-formed, the program is ill-formed[.](#stmt.do-1.sentence-1)

[2](#stmt.do-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L655)

In the do statement, the substatement is executed repeatedly
until the value of the expression becomes false[.](#stmt.do-2.sentence-1)

The test takes
place after each execution of the statement[.](#stmt.do-2.sentence-2)

### [8.6.4](#stmt.for) The for statement [[stmt.for]](stmt.for)

[1](#stmt.for-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L663)

The for statement

for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]")opt ; [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")opt ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")

is equivalent to

{  
 [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")  
 while ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) {  
 [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
 [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ;  
 }  
}

except that the [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") is
in the same scope as the [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]"), and
except that acontinue in [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") (not enclosed in another
iteration statement) will execute [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") before
re-evaluating [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]")[.](#stmt.for-1.sentence-1)

[*Note [1](#stmt.for-note-1)*:

Thus the first statement specifies initialization for the loop; the
condition ([[stmt.pre]](stmt.pre "8.1 Preamble")) specifies a test, sequenced before each
iteration, such that the loop is exited when the condition becomesfalse; the expression often specifies incrementing that is
sequenced after each iteration[.](#stmt.for-1.sentence-2)

â *end note*]

[2](#stmt.for-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L693)

Either or both of the [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") and the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") can be omitted[.](#stmt.for-2.sentence-1)

A missing [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") makes the implied while clause
equivalent to while (true)[.](#stmt.for-2.sentence-2)

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

[1](#stmt.ranged-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L703)

The range-based for statement

for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") : [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")

is equivalent to

{  
 [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt  
 auto &&*range* = [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ;  
 auto *begin* = *begin-expr* ;  
 auto *end* = *end-expr* ;  
 for ( ; *begin* != *end*; ++*begin* ) {  
 [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") = * *begin* ;  
 [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
 }  
}

where

- [(1.1)](#stmt.ranged-1.1)

if the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]"),
it is regarded as if it were surrounded by parentheses (so that a comma operator
cannot be reinterpreted as delimiting two [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]")*s*);

- [(1.2)](#stmt.ranged-1.2)

*range*, *begin*, and *end* are variables defined for
exposition only; and

- [(1.3)](#stmt.ranged-1.3)

*begin-expr* and *end-expr* are determined as follows:
  * [(1.3.1)](#stmt.ranged-1.3.1)

      if the type of *range* is a reference to an
array type R, *begin-expr* and *end-expr* are*range* and *range* + N, respectively,
where N is
the array bound[.](#stmt.ranged-1.3.1.sentence-1)
      If R is an array of unknown bound or an array of
incomplete type, the program is ill-formed;

  * [(1.3.2)](#stmt.ranged-1.3.2)

      if the type of *range* is a reference to a
class type C, and
searches in the scope of C ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))
for the names begin and end each find at least one declaration,*begin-expr* and *end-expr* are*range*.begin() and *range*.end(),
respectively;

  * [(1.3.3)](#stmt.ranged-1.3.3)

      otherwise, *begin-expr* and *end-expr* arebegin(*range*) and end(*range*), respectively,
where begin and end undergo
argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#stmt.ranged-1.3.3.sentence-1)
      [*Note [1](#stmt.ranged-note-1)*:
      Ordinary unqualified lookup ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup")) is not
performed[.](#stmt.ranged-1.3.3.sentence-2)
 â *end note*]

[*Example [1](#stmt.ranged-example-1)*: int array[5] = { 1, 2, 3, 4, 5 };for (int& x : array) x *= 2; â *end example*]

[*Note [2](#stmt.ranged-note-2)*:

The lifetime of some temporaries in the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is extended to cover the entire loop ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#stmt.ranged-1.sentence-2)

â *end note*]

[*Example [2](#stmt.ranged-example-2)*: 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 g() extendedfor (auto e : f2(g())) {} // undefined behavior} â *end example*]
