这是一个C11匿名结构吗?
我正在调查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都抱怨这名未透露姓名的成员,并表示该声明无效。 我做错了什么,或者他们根本不支持这个function?
不,那不是一个未命名的成员。
一个例子是:
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增加了在另一个结构中定义嵌套匿名结构的能力,但只能在此时定义一个新的匿名结构类型。 您不能拥有以前定义的类型的匿名结构成员。 语言可以被定义为允许它,并且语义(我认为)相当简单 – 但是定义两种不同的方法来做同样的事情并没有多大意义。 (对于上面的“struct”,请阅读“struct or union”。)
引用N1570草案 (非常接近2011版ISO C标准),第6.7.2.1节第13段:
类型说明符是没有标记的结构说明符的未命名成员称为匿名结构 ; 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合 。 匿名结构或联合的成员被视为包含结构或联合的成员。 如果包含的结构或联合也是匿名的,则递归应用。
结构说明符由关键字struct
,后跟可选标识符(本例中省略的标记),后跟{
和}
包含的一系列声明组成。 在您的情况下, AToW
是类型名称,而不是结构说明符,因此它不能用于定义匿名结构 。