Overriding a variable in ranges for loops

This code does not work with GCC 4.8.1, but works with MSVC2013:

#include <vector>
#include <string>

int main()
{
  std::vector<int> V{1,2,3,4,5};

  for (auto i : V)
  {
    std::string i = "oups";
  }
}

GCC 4.8.1 reports:

prog.cpp:10:17: error: redeclaration of ‘std::string i’
     std::string i = "oups";
                 ^

Is this some kind of error in the MSVC 2013 compiler?

+3
source share
3 answers

Yes, this is a mistake, but in GCC. C ++ 11 [stmt.ranged] clearly states that your range-based loop is forequivalent to this:

{
  auto && __range = (V);
  for ( auto __begin = __range.begin(),
             __end = __range.end();
        __begin != __end;
        ++__begin ) {
    auto i = *__begin;
    {
      std::string i = "oups";
    }
  }
}

Thus, the inside ishould simply hide the loop control iwithout any problems.

And, as this living example shows , the GCC actually agrees with this simply.

+4
source

His mistake in GCC as well as Clang

.

for ( range_declaration : range_expression ){ loop_statement }

{
auto && __range = range_expression ; 
     for (auto __begin = begin_expr,
        __end = end_expr; 
        __begin != __end; ++__begin) { 
           range_declaration = *__begin;
            {  // Notice brace
               loop_statement 
            } // Notice ending brace
} 
} 

, Visual ++ 2013

for (auto i : V) std::string i = "oups"; 
       /* match this with equivalent for-loop
          loop-statement aren't in braces
      */

.

+1

C ++ 11 [stmt.ranged] reports that the range-for loop expands to this:

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

Unlike other answers, I argue that there are no scope for statements and that this is an MSVC error (not gcc or clang).

0
source

Source: https://habr.com/ru/post/1667506/


All Articles