这是一个C11匿名结构吗?

Joh*_*itb 6 c struct c11 anonymous-struct

我正在调查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;
Run Code Online (Sandbox Code Playgroud)

Clang和GCC都抱怨这位未透露姓名的成员,并说该声明没有效果.我做错了什么,还是他们根本不支持这个功能呢?

Kei*_*son 6

不,那不是一个未命名的成员.

一个例子是:

struct outer {
    int a;
    struct {
        int b;
        int c;
    };
    int d;
};
Run Code Online (Sandbox Code Playgroud)

含内部结构部件bc无名构件struct outer.此未命名成员的成员bc,被视为包含结构的成员.

对于包含的联合而不是包含的结构,这可能更有用.特别是,它可用于定义类似于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;
        };
    };
};
Run Code Online (Sandbox Code Playgroud)

这可让您指的i,dp直接作为成员的struct variant对象,而不是对变化部分创造一个人工的名称.如果某些变体需要多个成员,则可以在匿名联合中嵌套匿名结构.

(它与Pascal和Ada的不同之处在于,根据type成员的价值,没有机制强制执行哪个变体是活跃的;那对你来说是C.)

在您的示例中,AToW是您之前定义的结构类型的typedef.你不被允许裸露

AToW;
Run Code Online (Sandbox Code Playgroud)

在结构定义的中间,你可以拥有一个裸露的东西

int;
Run Code Online (Sandbox Code Playgroud)

C11增加了在另一个结构中定义嵌套匿名结构的能力,但只能在此时定义一个新的匿名结构类型.您不能拥有先前定义类型的匿名结构成员.语言可以被定义为允许它,并且语义(我认为)相当简单 - 但是定义两种不同的方法来做同样的事情并没有多大意义.(对于上面的"struct",请阅读"struct or union".)

引用N1570草案(非常接近2011版ISO C标准),第6.7.2.1节第13段:

类型说明符是没有标记的结构说明符的未命名成员称为匿名结构 ; 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.如果包含的结构或联合也是匿名的,则递归应用.

结构说明符由关键字struct,随后的可选标识符(标记,在这种情况下被省略),随后封闭在声明的序列{}.在您的情况下,AToW是类型名称,而不是结构说明符,因此它不能用于定义匿名结构.