Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

Are nested range-based for statements strictly legal?

Consider this code:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> v1 {1,2};
    std::vector<int> v2 {4,5};
    for (auto i : v1) {
       for (auto j : v2) {
          std::cout << i << ',' << j << '\n';
       }
    }
}

As expected, GCC 4.8 compiles it just fine, and the output is:

1,4
1,5
2,4
2,5

However, C++11 defines ranged-for thus:

{
   auto && __range = range-init;
   for ( auto __begin = begin-expr,
              __end = end-expr;
        __begin != __end;
        ++__begin ) {
     for-range-declaration = *__begin;
     statement
   }
}

It does say:

__range, __begin, and __end are variables defined for exposition only

but it doesn't clarify that each ranged-for statement should expand to code in which each of those variables is unique, and therefore does not hide the same variables in an enclosing ranged-for.

To that end, it seems to me that nested ranged-for statements are not guaranteed to work as one would expect.

Are we sure that this is not a defect?

Upvotes: 1

Views: 202

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

Yes, it's perfectly and strictly legal.

The whole definition of ranged-for, despite being almost unique in the standard in its being given in terms of code, is not a simple expansion: this structure is designed to be expanded inside a compiler using intermediate representations of all the operations required.

In short, the use of the term "exposition" means this is all effectively pseudo-code anyway.

Besides, if you look closely at the scoping of those variables, there's no way they can conflict with the specified usage same variables declared in an enclosing ranged-for statement, and our own statement cannot access them anyway. That is, there is no situation in which any hiding of those loop variables could cause unexpected behaviour.

Upvotes: 9

Related Questions