Life-time of object declared in the second "parameter" of 'for' statement

Viewed 200

I have just discovered that it is possible to place a declaration also in the second "parameter" of a for-statement. But I was not able to find anywhere how it behaves with regard to the construction/destruction of the object declared in that parameter.

Let's have this simple code:

struct C {
  C() { puts("constr"); }
  ~C() { puts("destr"); }
};

int main() {
  for (int i = 0; auto h = std::make_unique<C>(); i++) {
    puts("in");
  }
}

Please could you tell me when h is destroyed? (after puts("in"), i++, ...?). How does it behave with break; and continue;?

Thanks for clarification!

2 Answers

The lifetime of the object created within the loop condition is bound to the scope of the loop body, and can also be used within the iteration expression (i++ in your example). The condition is evaluated at the beginning of each iteration, the object it creates lasts until the end of that iteration, is then destroyed and created again for the next iteration, and so on. break or continue statements do not influence the lifetime of the object created in the condition.

The reasoning is as follows. From [stmt.for], we can see that a for loop is defined in terms of a while loop.

The for statement

for ( init-statement condition ; expression ) statement

is equivalent to

{
    init-statement
    while ( condition ) {
        statement
        expression ;
    }
}

Jumping back to [stmt.while] then yields the answer to your question (emphasis mine):

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 whose condition is an initialized declaration of some variable t is equivalent to

label:
{ // start of condition scope
    condition; // declares t
    if (t) {
        statement
        goto label;
    }
} // end of condition scope

[ Note: The variable created in the condition is destroyed and created with each iteration of the loop. [...]]

Think it simple, if I'm the language designer, the following statements:

for ( a; b; c ) d

and

for ( a; { b }; { c }) { d }

Should be strictly equivalent

It is obvious that some variables defined in a can be used in b,c,d, So only a is special.

BTW

I think the for-statement in Scala is more beautiful. In Scala for is just a syntax suger:

for (i <- v) s  <==> v.foreach(i => s)

Where

i => s

is the lamba syntax like:

[](auto i){ s }

in C++11

It is universal true, variable v of every type which defines function foreach can be used in for statement.

Related