【问题标题】:Anonymous struct with ANSI CANSI C 的匿名结构
【发布时间】:2016-03-30 20:33:46
【问题描述】:

我想知道是否可以在 ANSI C 中声明匿名结构。我的代码是:

struct A
{
    int x;
};

struct B
{
    struct A;
    int y;
};

当我编译它时,我得到: 警告:声明没有声明任何内容

我已经读到标志 -fms-extensions 可以解决问题,但是它只适用于 Windows 系统,因为它产生: 警告:匿名结构是 Microsoft 扩展 [-Wmicrosoft]

我可以使用任何 ANSI 等效扩展吗?

【问题讨论】:

  • 没有标识符的struct?不,我不这么认为。你可以声明一个struct,不带类型名称,但带有struct {} identifier; 的标识符。 structs 的成员具有不同的范围,那么如果没有标识符,如何处理成员?
  • ANSI C 没有这个特性。您是否仅限于使用 ANSI C 或者也可以使用 C99 或 C11?
  • 我可以使用C99和C11,有什么解决方案吗?
  • @KlasSegeljakt 是的。 C11 提供匿名结构。让我修改我的答案。

标签: c ansi anonymous-struct


【解决方案1】:

在 ANSI C 中获得几乎此功能的一个技巧是使用适当的宏:

struct A {
    int x;
};

struct B {
    struct A A_;
    int y;
};

#define bx A_.x

那么你可以简单地做

struct B foo, *bar;

foo.bx;
bar->bx;

不过,在 C11 中,匿名结构是受支持的,您可以这样做

struct B {
    struct {
        int x;
    };

    int y;
}

可惜不是

struct A {
    int x;
};

struct B
{
    struct A;
    int y;
};

由于必须在结构内部声明匿名结构,因此它是匿名的。

有关 C11 中匿名成员的更多详细信息,请参阅 this answer

【讨论】:

    【解决方案2】:

    可以声明匿名结构和联合。 ISO C11 添加了这个特性,GCC 允许它作为extension

    C11 节 §6.7.2.1 第 13 段:

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

    19 下面说明了匿名结构和联合:

    struct v {
        union { // anonymous union
              struct { int i, j; }; // anonymous structure
              struct { long k, l; } w;
        };
        int m; 
    } v1; 
    
    v1.i = 2;   // valid
    v1.k = 3;   // invalid: inner structure is not anonymous
    v1.w.k = 5; // valid 
    

    现在只需使用foo.b 即可访问b

    【讨论】:

    • 您应该澄清这是 C11 中的新功能,因为 OP 正在谈论 ANSI C。另外,感谢您以精简的形式复制我的答案内容。
    • @FUZxxl;在您看来,内容来自您的答案,但事实并非如此。我从here 中拿了那个例子并稍微改变了它。顺便说一句,现在更改了整个内容。
    • 我没有说你接受了我的回答。我说您的回答是多余的,因为它说的与我在回答中所说的相同(有些浓缩)。但无论如何,我不应该在意。
    【解决方案3】:

    我想你想要这样的东西:

    struct B {
        struct {
            int x;
        } A;
        int y;
    };
    

    你可以这样做:

    struct B b;
    b.A.x = 5;
    printf( "%d\n", b.A.x );
    

    【讨论】:

    • 不,这不是匿名的:你仍然需要使用foo.A.x 而不是想要的foo.x
    猜你喜欢
    • 2013-04-18
    • 2020-10-28
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2013-05-19
    • 1970-01-01
    • 2018-01-05
    相关资源
    最近更新 更多