title: Redeclaration of a variable in a for-loop in C++
body: <p>When trying to compile the following (simplified) code for multiple platforms, I found that it was failing on some, namely IBM's xlC_r.  Further investigation has found that it also fails on comeau and clang.  It compiles successfully with g++ and Solaris's CC.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>int main()
  {
      int a1[1];
      bool a2[1];
  
      for (int *it = a1, *end = a1+1; it != end; ++it) {
          //...
          bool *jt = a2, *end = a2+1;
          //...
      }
  }
  </code></pre>
  
  <p>xlC_r error:</p>
  
  <pre><code>"main.cpp", line 8.25: 1540-0400 (S) "end" has a conflicting declaration.
  "main.cpp", line 6.25: 1540-0425 (I) "end" is defined on line 6 of "main.cpp".
  </code></pre>
  
  <p>clang error:</p>
  
  <pre><code>main.cpp:8:25: error: redefinition of 'end' with a different type
          bool *jt = a2, *end = a2+1;
                          ^
  main.cpp:6:25: note: previous definition is here
      for (int *it = a1, *end = a1+1; it != end; ++it) {
                          ^
  </code></pre>
  
  <p>comeau error:</p>
  
  <pre><code>"ComeauTest.c", line 8: error: "end", declared in for-loop initialization, may not
            be redeclared in this scope
            bool *jt = a2, *end = a2+1;
                            ^
  </code></pre>
  
  <p>The question is why is this an error?</p>
  
  <p>Looking through the 2003 standard, it says the following (6.5.3):</p>
  
  <pre><code>The for statement
      for ( for-init-statement; condition; expression ) statement
  is equivalent to
      {
          for-init-statement;
          while ( condition ) {
              statement;
              expression;
          }
      }
  except that names declared in the for-init-statement are in the same
  declarative-region as those declared in condition
  </code></pre>
  
  <p>Here there are no names declared in condition.</p>
  
  <p>Further, it says (6.5.1):</p>
  
  <pre><code>When the condition of a while statement is a declaration, the scope
  of the variable that is declared extends from its point of declaration
  (3.3.1) to the end of the while statement. A while statement of the form
      while (T t = x) statement
  is equivalent to
      label:
      {
          T t = x;
          if (t) {
              statement;
              goto label;
          }
      }
  </code></pre>
  
  <p>Again, I'm not sure this is relevant, as there is no declaration in the condition.  So given the equivalent re-write from 6.5.3, my code should be the same as:</p>
  
  <pre><code>int main()
  {
      int a1[1];
      bool a2[1];
  
      {
          int *it = a1, *end = a1+1;
          while (it != end) {
              //...
              bool *jt = a2, *end = a2+1;
              //...
              ++it;
          }
      }
  }
  </code></pre>
  
  <p>Which obviously would allow end to be re-declared.</p>