结构中的匿名联合不在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的可选项。