结构中的匿名联合不在c99中?
这里是非常简化的问题我有:
enum node_type { t_int,t_double }; struct int_node { int值; }; struct double_node { 双重价值; }; struct node { 枚举node_typetypes; 联合{ struct int_node int_n; struct double_node double_n; }; }; int main(void){ struct int_node i; i.value = 10; struct node n; n.type = t_int; ñ。 int_n = i; 返回0; }
我不明白的是:
$ cc us.c $ cc -std = c99 us.c us.c:18:4:警告:声明不声明任何东西 us.c:在函数'main'中: us.c:26:4:错误:“struct node”没有名为“int_n”的成员
使用没有-std
选项的GCC
没有任何问题编译上面的代码(和类似的代码工作得很好),但似乎c99
不允许这种技术。 为什么是这样,是否有可能使c99
(或c89
, c90
)兼容? 谢谢。
匿名联合是GNU扩展,不是任何标准版本的C语言的一部分。 你可以使用-std = gnu99或类似于c99 + GNU扩展的东西,但最好编写适当的C,而不要依赖只提供语法糖的扩展。
编辑:匿名联合在C11中添加,所以他们现在是语言的标准部分。 据推测GCC的-std=c11
可以让你使用它们。
我在其他人做了大约一年半的时间后发现了这个问题,所以我可以给出一个不同的答案:匿名结构不在C99标准中,但是它们是C11标准。 GCC和clang已经支持这个(C11标准似乎已经提升了微软的function,GCC已经为一些MSFT扩展提供了一段时间的支持)。
那么,解决scheme是命名联合实例(它可以保持匿名作为数据types),然后使用该名称作为代理。
$ diff -u old_us.c us.c --- old_us.c 2010-07-12 13:49:25.000000000 +0200 +++ us.c 2010-07-12 13:49:02.000000000 +0200 @@ -15,7 +15,7 @@ 联合{ struct int_node int_n; struct double_node double_n; - }; +}数据; }; int main(void){ @@ -23,6 +23,6 @@ i.value = 10; struct node n; n.type = t_int; - n.int_n = i; + n.data.int_n = i; 返回0; }
现在它编译为c99
没有任何问题。
$ cc -std = c99 us.c $
注意:我不喜欢这个解决scheme。
联盟必须有一个名称,并声明如下:
union UPair { struct int_node int_n; struct double_node double_n; }; UPair X; X.int_n.value = 12;
另一个解决scheme是将公共标题值( enum node_type type
)放到每个结构中,并使顶层结构成为一个联合体。 这不完全是“不要重复自己”,但它确实避免匿名工会和不舒服的代理值。
enum node_type { t_int, t_double }; struct int_node { enum node_type type; int value; }; struct double_node { enum node_type type; double value; }; union node { enum node_type type; struct int_node int_n; struct double_node double_n; }; int main(void) { union node n; n.type = t_int; // or n.int_n.type = t_int; n.int_n.value = 10; return 0; }
看看C99的6.2.7.1,我看到标识符是可选的:
struct-or-union-specifier: struct-or-union identifier-opt { struct-declaration-list } struct-or-union identifier struct-or-union: struct union struct-declaration-list: struct-declaration struct-declaration-list struct-declaration struct-declaration: specifier-qualifier-list struct-declarator-list ; specifier-qualifier-list: type-specifier specifier-qualifier-list-opt type-qualifier specifier-qualifier-list-opt
我一直在上下search,找不到任何违背规范的匿名工会。 整个-opt后缀表示事件,在这种情况下identifier
是根据6.1的可选项。