简体   繁体   English

这是一个C11匿名结构吗?

[英]Is this a C11 anonymous struct?

I was looking into the C11 draft and it says 我正在调查C11草案,它说

An unnamed member of structure type with no tag is called an anonymous structure; 没有标记的结构类型的未命名成员称为匿名结构; an unnamed member of union type with no tag is called an anonymous union. 没有标记的联合类型的未命名成员称为匿名联合。 The members of an anonymous structure or union are considered to be members of the containing structure or union. 匿名结构或联合的成员被视为包含结构或联合的成员。

So I constructed the following testcase 所以我构建了以下测试用例

// 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 and GCC both complain about the unnamed member, saying that the declaration has no effect. Clang和GCC都抱怨这位未透露姓名的成员,并说该声明没有效果。 Did I do something wrong, or do they simply not support that feature yet? 我做错了什么,还是他们根本不支持这个功能呢?

No, that's not an unnamed member. 不,那不是一个未命名的成员。

An example is: 一个例子是:

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

The inner structure containing members b and c is an unnamed member of struct outer . 包含成员bc的内部结构是struct outer未命名成员 The members of this unnamed member, b and c , are considered to be members of the containing structure. 此未命名成员bc成员被视为包含结构的成员。

This is probably more useful with a contained union rather than a contained structure. 对于包含的联合而不是包含的结构,这可能更有用。 In particular, it can be used to define something similar to a Pascal or Ada variant record: 特别是,它可用于定义类似于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;
        };
    };
};

This lets you refer to i , d , and p directly as members of a struct variant object rather than creating an artificial name for the variant portion. 这使您可以直接将idp称为struct variant对象的成员,而不是为变体部分创建人工名称。 If some variants require more than one member, you can nest anonymous structures within the anonymous union. 如果某些变体需要多个成员,则可以在匿名联合中嵌套匿名结构。

(It differs from Pascal and Ada in that there's no mechanism to enforce which variant is active given the value of the type member; that's C for you.) (它与Pascal和Ada的不同之处在于,在给定type成员的值的情况下,没有机制来强制执行哪个变体是活动的;那对你来说是C。)

In your example, AToW is a typedef for a struct type that you defined previously. 在您的示例中, AToW是您之前定义的结构类型的typedef。 You're not permitted to have a bare 你不被允许裸露

AToW;

in the middle of a struct definition, any more than you can have a bare 在结构定义的中间,你可以拥有一个裸露的东西

int;

C11 added the ability to define a nested anonymous struct within another struct, but only by defining a new anonymous struct type at that point. C11增加了在另一个结构中定义嵌套匿名结构的能力,但只能在此时定义一个新的匿名结构类型。 You can't have an anonymous struct member of a previously defined type. 您不能拥有先前定义类型的匿名结构成员。 The language could have been defined to permit it, and the semantics would (I think) be reasonably straightforward -- but there wasn't much point in defining two different ways to do the same thing. 语言可以被定义为允许它,并且语义(我认为)相当简单 - 但是定义两种不同的方法来做同样的事情并没有多大意义。 (For "struct" in the above, read "struct or union".) (对于上面的“struct”,请阅读“struct or union”。)

Quoting the N1570 draft (which is very close to the released 2011 ISO C standard), section 6.7.2.1 paragraph 13: 引用N1570草案 (非常接近2011版ISO C标准),第6.7.2.1节第13段:

An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure ; 类型说明符是没有标记的结构说明符的未命名成员称为匿名结构 ; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union . 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合 The members of an anonymous structure or union are considered to be members of the containing structure or union. 匿名结构或联合的成员被视为包含结构或联合的成员。 This applies recursively if the containing structure or union is also anonymous. 如果包含的结构或联合也是匿名的,则递归应用。

A structure specifier consists of the keyword struct , followed by an optional identifier (the tag, omitted in this case), followed by a sequence of declarations enclosed in { and } . 结构说明符由关键字struct ,后跟可选标识符(本例中省略的标记),后跟{}包含的一系列声明组成。 In your case, AToW is a type name, not a structure specifier, so it can't be used to define an anonymous structure . 在您的情况下, AToW是类型名称,而不是结构说明符,因此它不能用于定义匿名结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM