Declaring anonymous struct in for loop, clang fails to compile

c, c99

Solution

I'm respectfully unconvinced by the previous answers. It builds successfully with gcc (with `-Wall -pedantic`), only not with clang nor Visual Studio.

Microsoft have acknowledged as a bug an extremely similar issue with Visual Studio at this Microsoft Connect bug item.

6.8.5 is saying that declarations of identifiers inside the for-init-expression cannot be `typedef`, `extern` or `static` (the only storage class specifiers other than `auto` and `register`).

The storage class specifier `auto` in C99 is default and is implicit. The struct type and identifier `i` are then auto (have scope within that code block). Surely the code is then valid? I don't see how 6.8.5 is forbidding the declaration of a type.

I suggest that gcc is correct, and it's a bug with the implementation by clang and Visual Studio.

Problem

Code declaring anonymous structs in a for loop worked fine in gcc with -std=c99/gnu99 ``` for (struct {int foo; int bar;} i = {0}; i.foo < 10; i.foo++); ``` However when I switch to clang instead I got the error: ``` error: declaration of non-local variable in 'for' loop ``` Why is this an error? Why would it allow some types (e.g. "int") but not others (e.g. struct {int foo;}) ? This seems inconsistent. Does clang fail to implement c99 correctly or is that code invalid c99 and gcc just happens to support it? Does anyone know of a way to declare more than one type of variable in a for loop that is supported by clang? (This is useful for macros.) EDIT: Since people asked why this is useful I will paste some example code: ``` #define TREE_EACH(head, node, field, iterator) for ( \ /* initialize */ \ struct { \ node* cur; \ node* stack[((head)->th_root == 0? 0: (head)->th_root->field.avl_height) + 1]; \ uint32_t stack_size; \ } iterator = {.cur = (head)->th_root, .stack_size = 0}; \ /* while */ \ iterator.cur != 0; \ /* iterate */ \ (iterator.stack_size += (iterator.cur->field.avl_right != 0) \ ? (iterator.stack[iterator.stack_size] = avl_right, 1) \ : 0), \ (iterator.cur = (iterator.cur->field.avl_left == 0) \ ? iterator.cur->field.avl_left \ : (iterator.stack_size > 0? (iterator.stack_size--, iterator.stack[iterator.stack_size]): 0)) \ ) ``` This is a really convenient macro that I wrote which iterates over an AVL tree in depth-first order on the stack. Since declaring anonymous structs in the for loop is not allowed though I have to make the macro less intuitive to use. I could not possible out-source the declaration to the rest of the tree since it uses a variable length array.

Original source