使用 ANSI C 的匿名结构体

3
我想知道在 ANSI C 中是否可以声明匿名结构体。我现有的代码是:
struct A
{
    int x;
};

struct B
{
    struct A;
    int y;
};

当我编译它时,我收到了警告: 警告:声明未声明任何内容

我已经阅读了使用-fms-extensions标志,它只在Windows系统上有效,因为它会产生: 警告:匿名结构体是Microsoft扩展[-Wmicrosoft]

是否有任何ANSI等效扩展可以使用?


一个没有标识符的 struct?不,我不这么认为。你可以声明一个没有类型名称但有标识符的 struct,如 struct {} identifier;struct 的成员具有独特的作用域,那么如果没有标识符,成员该如何被引用呢? - cadaniluk
2
ANSI C 不支持此特性。您是否受限于 ANSI C,还是可以使用 C99 或 C11? - fuz
我可以使用C99和C11,有没有针对这些的解决方案? - Klas. S
2
@KlasSegeljakt 是的。C11提供了匿名结构体。让我修改我的答案。 - fuz
3个回答

3

在 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中匿名成员的更多详细信息,请参见此答案


3
可以声明匿名的结构体和联合体。ISO C11添加了这个特性,GCC允许使用扩展
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

4
你应该澄清这是C11中的新内容,因为OP在谈论ANSI C。还有,感谢你以简洁的形式复制了我的答案内容。 - fuz
@FUZxxl; 你可能认为这个内容是从你的回答中提取的,但实际上并不是。我是从这里拿了一个例子,并进行了一些修改。顺便说一句,现在已经改变了整个内容。 - haccks
1
我并不是说你抄袭了我的答案。我只是觉得你的回答有些冗余,因为它所表达的内容与我的回答相同(略微压缩)。但无论如何,这都不应该让我在意。 - fuz

-1
你想要这样的东西吧:
struct B {
    struct {
        int x;
    } A;
    int y;
};

你可以这样做:

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

3
不,这并不是匿名的:你仍然需要执行 foo.A.x 而不是想要的 foo.x - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接