在for循环中声明匿名结构,clang无法编译 [英] Declaring anonymous struct in for loop, clang fails to compile

查看:116
本文介绍了在for循环中声明匿名结构,clang无法编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在for循环中声明匿名结构的代码在带有-std = c99 / gnu99的gcc中可以正常工作

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++);

但是当我改用clang时,却出现错误:

However when I switch to clang instead I got the error:

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

为什么会出错?为什么要允许某些类型(例如 int)而不允许其他类型(例如struct {int foo;})?这似乎不一致。 clang是否无法正确实现c99还是代码无效的c99和gcc恰好支持c99?

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?

有人知道一种声明多种类型变量的方法吗?在clang支持的for循环中? (这对宏很有用。)

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

编辑:

由于人们问为什么这有用,所以我将粘贴一些示例代码:

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

这是我写的一个非常方便的宏,它按深度优先顺序遍历AVL树堆栈。由于不允许在for循环中声明匿名结构,尽管我不得不使宏使用起来不那么直观。我无法将声明外包到树的其余部分,因为它使用了可变长度的数组。

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.

推荐答案

我对先前的答案深信不疑。它可以使用gcc(带有 -Wall -pedantic )成功构建,而不能仅使用clang或Visual Studio。

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

Microsoft在此 Microsoft Connect错误项

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

6.8.5表示 for-init-expression 中的标识符声明不能为 typedef extern static (除 auto <之外的唯一存储类说明符) / code>和注册)。

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

C99中的存储类说明符 auto 是默认值,是隐式的。然后,结构类型和标识符 i 是自动的(在该代码块中具有作用域)。代码肯定有效吗?我看不到6.8.5如何禁止类型的声明。

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.

我建议gcc是正确的,这是clang和Visual Studio实施的错误。

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

这篇关于在for循环中声明匿名结构,clang无法编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆