I saw this way to implement some kind of struct
inheritance with anonymous struct
in C11, and wanted to try it out. Here is what I have:
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;
}
Result from 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 */
Relevant:
$ gcc --version
gcc (Debian 6.3.0-18) 6.3.0 20170516
Is this not implemented in my compiler, or am I doing it wrong?
According to GCC reference : use -fms-extensions
flag, Which will enable the this feature.
Unless
-fms-extensions
is used, the unnamed field must be a structure or union definition without a tag (for example, ‘struct { int a; };’). If-fms-extensions
is used, the field may also be a definition with a tag such as‘struct foo { int a; };’
, a reference to a previously defined structure or union such as ‘struct foo;’, or a reference to a typedef name for a previously defined structure or union type.The option
-fplan9-extensions
enables-fms-extensions
as well as two other extensions. First, a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls.
I have used following command on GCC, it's working fine.
gcc -std=c11 -O2 -Wall -fms-extensions -pedantic -pthread ls.c
The standard only allows structure and unions without a tag as unnamed members:
6.7.2.1 Structure and union specifiers - Paragraph 13
An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.
Yours clearly has a tag, so it's not valid C. What the answer you linked to did is not any better either. The way to do it in a standard compliant way, is sadly quite verbose:
struct struct_b {
union {
struct struct_a _aa;
struct { int aa; };
};
int bb;
};
Which really isn't anything to be impressed by. One can perhaps use a macro to avoid repeating the member declarations, but it's a code smell by now.
It appears you are attempting to make an anonymous unnamed struct containing int aa
in struct_b
, similar to the following:
#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;
}
Example Use/Output
$ ./bin/strc2
my_b.aa: 5
my_b.bb: 6
This follows directly from the standard section cited by StoryTeller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With