Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

range based for loop with existing variable

Tags:

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; } 
  1. MSVC 2013 doesn't seem to support range based for loops without type declaration
  2. 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.

like image 344
Niklas R Avatar asked Jul 27 '16 13:07

Niklas R


Video Answer


2 Answers

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.

like image 133
TartanLlama Avatar answered Sep 18 '22 10:09

TartanLlama


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

like image 21
marcinj Avatar answered Sep 19 '22 10:09

marcinj