C11结构继承与匿名结构

问题描述:

我看到this way在C11中实现某种struct继承与匿名struct,并且想试用它。以下是我有:从GCCC11结构继承与匿名结构

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 -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 

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

+1

的可能的复制[什么是匿名结构和联合的有用的C11?](https://*.com/questions/8932707/what-are-anonymous-structs-and-unions-useful-for -in-c11) –

+0

在'struct struct_b'声明中'struct struct_a;'之后需要一些东西。 –

+0

[也与此相关](https://*.com/a/44524573/2371524)..底线:为了确保您的代码毫无疑问符合您的要求,您必须使用非常详细的表单,不幸的是。 –

标准只允许结构和联合无标签作为无名成员:

6.7.2.1 Structure and union specifiers - Paragraph 13

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

你很明显有一个标签,所以它是无效的C.你连接的答案并没有更好的。做一个符合标准的方式的方式,可悲的是非常详细:

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

这真的是没有什么被留下深刻印象。人们可以使用宏来避免重复成员声明,​​但现在它是一种代码异味。

+0

如果有任何事情尝试使用'_aa'的地址,那么该版本的代码将在别名规则的“现代”解释下失败并使用结果指针访问结构。 – supercat

似乎要尝试使含有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引用。

+0

我明白了。如果需要在那里显式定义内部结构的成员,那么分组的意义是什么? – Gauthier

+0

这就是100美元的问题。我已经玩了一下,添加了多个层次和多种类型,并且我没有看到在结构中嵌入匿名匿名结构的好处。似乎我只是在原始结构本身中声明变量更有意义。我必须看到标准委员会的会议记录,但是我怀疑这是为了“位域”目的在“union”中提供匿名的未命名'struct',事实上你可以使用结构只是工会和结构以相同方式处理的副作用。 –

+0

@ DavidC.Rankin:标准是恕我直言,在那里非常可怕,尤其是考虑到“现代”别名规则,它假定出现在联合中的未标记结构不会使用相同成员来标记标记结构。 – supercat

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

  • 除非使用-fms-extensions,无名字段必须是结构或联合定义没有标记(例如,“结构{ INT一个;};”)。如果使用-fms-extensions,则字段还可以是具有诸如‘struct foo { int a; };’之类的标签的定义的 定义,参考 定义为先前定义的结构或联合(诸如“struct foo;”)或对先前定义的typedef名称的引用结构或 联合类型。

  • 选项-fplan9-extensions启用-fms-extensions以及另外两个扩展。首先,指向结构的指针 自动转换为指向匿名字段的指针,用于 赋值和函数调用。

我用下面的命令GCC,它的正常工作。

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