我正在调查C11草案并且说
没有标记的结构类型的未命名成员称为匿名结构;没有标记的联合类型的未命名成员称为匿名联合。匿名结构或联合的成员被视为包含结构或联合的成员。
所以我构建了以下测试用例
// struct type with no tag
typedef struct {
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
} AToW;
union
{
AToW; // <- unnamed member
unsigned char bytes[sizeof(AToW)];
} myUnion;
Clang和GCC都抱怨这名未透露姓名的成员,并表示该声明无效。我做错了什么,或者他们根本不支持这个功能呢?
答案 0 :(得分:6)
不,那不是一个未命名的成员。
一个例子是:
struct outer {
int a;
struct {
int b;
int c;
};
int d;
};
包含成员b
和c
的内部结构是struct outer
的未命名成员。此未命名成员b
和c
的成员被视为包含结构的成员。
对于包含的联合而不是包含的结构,这可能更有用。特别是,它可用于定义类似于Pascal或Ada变体记录的内容:
enum variant_type { t_int, t_double, t_pointer, t_pair };
struct variant {
enum variant_type type;
union {
int i;
double d;
void *p;
struct {
int x;
int y;
};
};
};
这使您可以直接将i
,d
和p
称为struct variant
对象的成员,而不是为变体部分创建人工名称。如果某些变体需要多个成员,则可以在匿名联合中嵌套匿名结构。
(它与Pascal和Ada的不同之处在于,鉴于type
成员的价值,没有机制强制执行哪个变体是活跃的;那对你来说是C的。)
在您的示例中,AToW
是您之前定义的结构类型的typedef。你不允许裸露
AToW;
在结构定义的中间,不仅仅是你可以有一个
int;
C11增加了在另一个结构中定义嵌套匿名结构的能力,但只能在此时定义一个新的匿名结构类型。您不能拥有先前定义类型的匿名结构成员。语言可以被定义为允许它,并且语义(我认为)相当简单 - 但是在定义两种不同的方法来做同样的事情时没有多大意义。 (对于&#34; struct&#34;在上面,阅读&#34; struct或union&#34;。)
引用N1570 draft(非常接近已发布的2011 ISO C标准),第6.7.2.1节第13段:
一个未命名的成员,其类型说明符是一个结构说明符 没有标记被称为匿名结构;一个未命名的成员,其类型 说明符是没有标记的联合说明符,称为匿名 联合。考虑匿名结构或联合的成员 成为包含结构或联盟的成员。这适用 如果包含的结构或联合也是匿名的,则递归地进行。
结构说明符由关键字struct
组成,后跟可选标识符(在本例中省略标记),后跟{{1}中包含的一系列声明}和{
。在您的情况下,}
是类型名称,而不是结构说明符,因此无法用于定义匿名结构。