The scope of the iterating variable begins too early, i.e. it is already available in the expression of the rhs. This is a problem if the rhs expression includes the same identifier which is shadowed by this issue. Simple case: int i[] = { }; for (int i : i); fails to compile because the rhs 'i' will be the same as the lhs 'i' which is not a valid expression for the range-based for-loop. The range-based for-loop is equivalent to some for-construct. According to the standard the above should compile because the scope of the lhs begins inside the body of this substituted for-loop. Just for completeness: The Evil case: class MyType { std::vector<MyType*> vec; public: const std::vector<MyType*>& foo() { return vec; } }; MyType * t = new MyType; for (MyType * t : t->foo()); this will not refuse to compile since everything is well-formed. The real problem is that foo isn't called on the previously defined t but on the new uninitialized t.
Just hit this bug in GCC 4.9. Again, the lhs side has scope before the rhs has been evaluated, which is against the standardese in section 6.5.4 of both N3936 and N3291.
*** Bug 57493 has been marked as a duplicate of this bug. ***
From PR57493: Google ref: b/9229787
I hit that one too with 5.2.
FWIW, it's on StackOverflow since May 2013. http://stackoverflow.com/questions/16407212/identifier-with-the-same-name-in-both-expression-and-declaration-of-range-based
*** Bug 65201 has been marked as a duplicate of this bug. ***
*** Bug 67584 has been marked as a duplicate of this bug. ***
Author: ville Date: Thu Oct 1 19:22:08 2015 New Revision: 228354 URL: https://gcc.gnu.org/viewcvs?rev=228354&root=gcc&view=rev Log: PR c++/54430 /cp 2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com> PR c++/54430 * name-lookup.c (push_binding): Make non-static. * name-lookup.h (push_binding): Declare it. * parser.c (cp_parser_range_for): Use it, get the range declaration away from the scope until the range expression has been parsed, then restore the declaration. /testsuite 2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com> PR c++/54430 * g++.dg/cpp0x/range-for30.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp0x/range-for30.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/name-lookup.c trunk/gcc/cp/name-lookup.h trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk.
*** Bug 69784 has been marked as a duplicate of this bug. ***
Author: jason Date: Fri Jul 15 18:38:31 2016 New Revision: 238391 URL: https://gcc.gnu.org/viewcvs?rev=238391&root=gcc&view=rev Log: PR c++/71604 - type definition in range-based for PR c++/54430 * parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly. (cp_parser_simple_declaration): Diagnose type definition in for-range-declaration. Added: trunk/gcc/testsuite/g++.dg/cpp0x/range-for31.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/testsuite/g++.dg/cpp0x/range-for8.C
Author: jason Date: Thu Jul 21 06:15:43 2016 New Revision: 238569 URL: https://gcc.gnu.org/viewcvs?rev=238569&root=gcc&view=rev Log: PR c++/71604 - type definition in range-based for PR c++/54430 * parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly. (cp_parser_simple_declaration): Diagnose type definition in for-range-declaration. Added: branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp0x/range-for31.C Modified: branches/gcc-6-branch/gcc/cp/ChangeLog branches/gcc-6-branch/gcc/cp/parser.c branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp0x/range-for8.C