Reputation: 4946
This code fails 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 tells:
prog.cpp:10:17: error: redeclaration of ‘std::string i’
std::string i = "oups";
^
Is it some bug in the MSVC 2013 compiler?
Upvotes: 3
Views: 1071
Reputation: 64223
c++11 [stmt.ranged] tells that the range-for loop expands into this :
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
Contrary to other answers, I am claiming there are no scopes for the statements, and that this is a MSVC's bug (not gcc or clang).
Upvotes: 0
Reputation: 47794
Its a bug in GCC, as well as Clang
for ( range_declaration : range_expression ){ loop_statement }
will be equivalent to
{
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
}
}
On another note, on Visual C++ 2013
for (auto i : V) std::string i = "oups";
/* match this with equivalent for-loop
loop-statement aren't in braces
*/
shouldn't compile.
Upvotes: 1
Reputation: 171127
Yes, it's a bug, but in GCC. C++11[stmt.ranged] clearly states that your range-based for
loop is equivalent to this:
{
auto && __range = (V);
for ( auto __begin = __range.begin(),
__end = __range.end();
__begin != __end;
++__begin ) {
auto i = *__begin;
{
std::string i = "oups";
}
}
}
So the inner i
should simply hide the loop-control i
without any problems.
And, as this live example shows, when spelled out like this, GCC actually accepts it just fine.
Upvotes: 4