C11结构继承与匿名结构

时间:2017-10-17 07:14:48

标签: c inheritance gcc struct c11

我看到this way要在C11中使用匿名struct实现某种struct继承,并想尝试一下。这就是我所拥有的:

struct struct_a {
    int aa;
};

struct struct_b {
    struct struct_a;
    int bb;
};

int main(void)
{
    volatile struct struct_b my_b;
    my_b.aa = 5; /* not a member of my_b */
    my_b.bb = 6;

}

来自gcc的结果:

$ gcc -std=c11 struct_extend.c 
struct_extend.c:11:20: warning: declaration does not declare anything
     struct struct_a;
                    ^
struct_extend.c: In function ‘main’:
struct_extend.c:18:9: error: ‘volatile struct struct_b’ has no member named ‘aa’
     my_b.aa = 5; /* not a member of my_b */

相关:

$ gcc --version
gcc (Debian 6.3.0-18) 6.3.0 20170516

这是不是在我的编译器中实现的,还是我做错了?

3 个答案:

答案 0 :(得分:4)

该标准仅允许没有标记的结构和联合作为未命名的成员:

6.7.2.1 Structure and union specifiers - Paragraph 13

  

未命名的成员,其类型说明符是结构说明符   没有标签被称为匿名结构;一个未命名的成员,其类型   说明符是没有标记的联合说明符,称为匿名   联盟。考虑匿名结构或联合的成员   成为包含结构或联盟的成员。这适用   如果包含的结构或联合也是匿名的,则递归地进行。

你们显然有一个标签,所以它无效C.你所链接的答案也没有更好。以符合标准的方式做到这一点的方式,遗憾的是非常冗长:

struct struct_b {
    union {
        struct struct_a _aa;
        struct { int aa; };
    };
    int bb;
};

真正没有什么值得印象的。也许可以使用宏来避免重复成员声明,​​但现在它是代码味道。

答案 1 :(得分:3)

根据GCC引用:使用-fms-extensions标志,这将启用此功能。

  
      
  • 除非使用-fms-extensions,否则未命名字段必须是没有标记的结构或联合定义(例如,'struct {   int a; };”)。如果使用-fms-extensions,则该字段也可以是   带有‘struct foo { int a; };’标记的定义,引用   到先前定义的结构或联合,例如'struct foo;'或a   引用先前定义的结构的typedef名称或   工会类型。

  •   
  • 选项-fplan9-extensions启用-fms-extensions以及其他两个扩展程序。首先,指向结构的指针是   自动转换为指向匿名字段的指针   作业和函数调用。

  •   

我在GCC上使用了以下命令,它工作正常。

gcc -std=c11 -O2 -Wall -fms-extensions -pedantic -pthread ls.c

答案 2 :(得分:1)

您似乎试图在int aa中创建一个包含struct_b的匿名未命名结构,类似于以下内容:

#include <stdio.h>

struct struct_b {
    struct {
        int aa;
    };
    int bb;
};

int main(void)
{
    volatile struct struct_b my_b;
    my_b.aa = 5; /* now a member of my_b */
    my_b.bb = 6;

    printf ("my_b.aa: %d\nmy_b.bb: %d\n", my_b.aa, my_b.bb);

    return 0;
}

示例使用/输出

$ ./bin/strc2
my_b.aa: 5
my_b.bb: 6

这直接来自StoryTeller引用的标准部分。