6

我正在研究 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 都抱怨这个未命名的成员,说声明没有效果。我做错了什么,还是他们根本不支持该功能?

4

1 回答 1

7

不,那不是无名成员。

一个例子是:

struct outer {
    int a;
    struct {
        int b;
        int c;
    };
    int d;
};

包含成员的内部结构bc是 的未命名成员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;
        };
    };
};

这使您可以将idp直接引用为对象的成员,struct variant而不是为变体部分创建人工名称。如果某些变体需要多个成员,您可以在匿名联合中嵌套匿名结构。

(它与 Pascal 和 Ada 的不同之处在于,在给定type成员的值的情况下,没有强制执行哪个变体处于活动状态的机制;这对你来说是 C。)

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

AToW;

在结构定义的中间,你不能有一个裸露的

int;

C11 添加了在另一个结构中定义嵌套匿名结构的能力,但只能通过在该点定义新的匿名结构类型。您不能拥有先前定义的类型的匿名结构成员。语言可以被定义为允许它,并且语义(我认为)会相当简单——但是定义两种不同的方式来做同样的事情并没有多大意义。(对于上面的“结构”,请阅读“结构或联合”。)

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

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

结构说明符由关键字组成struct,后跟一个可选标识符(标记,在这种情况下省略),后跟一系列用 and 括起来的{声明}。在您的情况下,AToW是类型名称,而不是结构说明符,因此它不能用于定义匿名结构

于 2014-05-07T20:07:17.160 回答