<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Can't initialize an anonymous struct in for loop"
   href="https://bugs.llvm.org/show_bug.cgi?id=35757">35757</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Can't initialize an anonymous struct in for loop
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>bo@bowild.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When trying to initialize an anonymous struct within a for loop, the following
error is displayed:

     error: declaration of non-local variable in 'for' loop

The error does not occur when using `gcc`.

This was discussed on StackOverflow and recognized as a bug by Microsoft
Virtual Studio's development team (though at the time they decided not to fix
the issue, see the comments in the bug report).

SO discussion:
<a href="https://stackoverflow.com/questions/11903232/declaring-anonymous-struct-in-for-loop-clang-fails-to-compile">https://stackoverflow.com/questions/11903232/declaring-anonymous-struct-in-for-loop-clang-fails-to-compile</a>

MVS bug
report:<a href="https://connect.microsoft.com/VisualStudio/feedback/details/624410/visual-c-compiler-fails-to-parse-a-for-init-statement-that-starts-with-a-class-specifier">https://connect.microsoft.com/VisualStudio/feedback/details/624410/visual-c-compiler-fails-to-parse-a-for-init-statement-that-starts-with-a-class-specifier</a>

This issue requires adding struct identifiers to the global namespace where
these can be avoided.

The following example was stripped from an implementation for a dynamic array
(this produces the error):

      #include <stdio.h>

      typedef struct fio_ary_s {
        unsigned long start;
        unsigned long end;
        unsigned long capa;
        void **arry;
      } fio_ary_s;

      /**
       * Iterates through the list using a `for` loop.
       *
       * Access the data with `pos.obj` and it's index with `pos.i`. the `pos`
       * variable can be named however you please.
       */
      #define FIO_ARY_FOR(ary, pos)                                            
     \
        for (                                                                  
     \
            struct {                                                           
     \
              unsigned long i;                                                 
     \
              void *obj;                                                       
     \
            } pos = {0, (ary)->arry[(ary)->start]};                            
     \
            (pos.i + (ary)->start) < (ary)->end;                               
     \
            (++pos.i), (pos.obj = (ary)->arry[pos.i + (ary)->start]))

      int main(void) {
        char *static_data[] = {"Hello ", "world"};
        fio_ary_s static_ary = (fio_ary_s){.arry = (void **)static_data, .end =
2};
        FIO_ARY_FOR(&static_ary, pos) {
          printf("index: %lu == %s\n", pos.i, (char *)pos.obj);
        }

        /* code */
        return 0;
      }

Changing the macro to use a non-anonymous struct will work around the issue,
but it will add redundant code as well as litter the namespace:

      struct fio_ary_pos_s {
        unsigned long i;
        void *obj;
      };
      #define FIO_ARY_FOR(ary, pos)                                            
     \
        for (struct fio_ary_pos_s pos = {0, (ary)->arry[(ary)->start]};        
     \
             (pos.i + (ary)->start) < (ary)->end;                              
     \
             (++pos.i), (pos.obj = (ary)->arry[pos.i + (ary)->start]))</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>