[llvm-bugs] [Bug 35757] New: Can't initialize an anonymous struct in for loop

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Dec 27 02:09:10 PST 2017


https://bugs.llvm.org/show_bug.cgi?id=35757

            Bug ID: 35757
           Summary: Can't initialize an anonymous struct in for loop
           Product: clang
           Version: unspecified
          Hardware: Macintosh
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: bo at bowild.com
                CC: llvm-bugs at lists.llvm.org

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:
https://stackoverflow.com/questions/11903232/declaring-anonymous-struct-in-for-loop-clang-fails-to-compile

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

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]))

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20171227/787197f9/attachment.html>


More information about the llvm-bugs mailing list