Using a range based for loop in C++11 with an existing variable, I would expect that variable to be filled with the value of the last iteration after the loop. However, I've gotten different results when I tested it.
Example:
#include <iostream> #include <vector> using namespace std; int main() { std::vector<int> v; v.push_back(2); v.push_back(43); v.push_back(99); int last = -50; for (last : v) std::cout << ":" << last << "\n"; std::cout << last; return 0; }
GCC-5.1 either automatically introduces a new variable or sets it back to the initial value, giving
:2
:43
:99
-50
I guess MSVC is just being MSVC again, but what about GCC here? Why is last
not 99
in the last line?
Given the definition by the standard, I would expect the behaviour I described in the first sentence.
{ auto && __range = range_expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
range_declaration
being last
and not int last
, this should modify the existing variable.
GCC implemented standards proposal n3994, which suggests that for (elem : range)
be syntactic sugar for for (auto&& elem : range)
. This didn't make it into C++17, so the functionality has been removed from more recent versions of GCC.
The named variable used to iterate over the range must be a declaration according to [stmt.ranged]
, so your code shouldn't compile.
Your code does not compile starting with gcc 6.1 (and for all clang versions):
main.cpp:12:8: error: range-based for loop requires type for loop variable for (last : v) ^ auto &&
it looks like previous versions used auto implicitly here. The fact that you get -50 as last output is because for
introduces local scope for last, so after for
ends, last from outer scope was used.
I did a little digging and this was on purpose under gcc: N3994, terse range-for, which shortly is doing following:
A range-based for statement of the form for ( for-range-identifier : for-range-initializer ) statement is equivalent to for ( auto&& for-range-identifier : for-range-initializer ) statement
then it didn`t make it to c++17 and was removed here:
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=229632
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With