这是一个C11匿名结构吗?

时间:2014-05-07 20:00:50

标签: 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;

Clang和GCC都抱怨这名未透露姓名的成员,并表示该声明无效。我做错了什么,或者他们根本不支持这个功能呢?

1 个答案:

答案 0 :(得分:6)

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

一个例子是:

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

包含成员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;
        };
    };
};

这使您可以直接将idp称为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}中包含的一系列声明}和{。在您的情况下,}是类型名称,而不是结构说明符,因此无法用于定义匿名结构