Gau*_*ier 3 c inheritance gcc struct c11
我看到了在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;
}
Run Code Online (Sandbox Code Playgroud)
来自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 */
Run Code Online (Sandbox Code Playgroud)
相关:
$ gcc --version
gcc (Debian 6.3.0-18) 6.3.0 20170516
Run Code Online (Sandbox Code Playgroud)
这不是在我的编译器中实现的,还是我做错了?
根据GCC参考:use -fms-extensions标志,它将启用此功能。
除非
-fms-extensions使用,否则未命名字段必须是不带标签的结构或联合定义(例如'struct {int a;};')。如果-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
Run Code Online (Sandbox Code Playgroud)
该标准只允许没有标签的结构和联合作为未命名成员:
类型说明符是不带标记的结构说明符的未命名成员称为匿名结构;类型说明符是不带标记的联合说明符的未命名成员称为匿名联合。匿名结构或联合的成员被视为包含结构或联合的成员。如果包含的结构或联合也是匿名的,则这会递归地应用。
你的显然有一个标签,所以它是无效的 C。你链接到的答案也没有更好。遗憾的是,以符合标准的方式执行此操作的方法相当冗长:
struct struct_b {
union {
struct struct_a _aa;
struct { int aa; };
};
int bb;
};
Run Code Online (Sandbox Code Playgroud)
这确实没有什么值得印象深刻的。也许可以使用宏来避免重复成员声明,但现在已经是一种代码味道了。