As an extension MSVC compiler (see Microsoft Specific Anonymous Structures) and gcc compiler with -fms-extensions
(see gcc docs unnamed fields) support the syntax of unnamed structures. When using this extension it allows the code to compiler and access the unnamed structure members as if they were members of the containing structure.
If using this extension, the code will compile and access is fine, you just made a typo c_st
should be d_st
.
#include <stdio.h>
union ab {
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
typedef struct d {
union ab;
} d_st;
int main(void) {
d_st c;
printf("%d\n", c.a_st.a);
}
Without using this extension, the code will not compile, as explained below.
is it necessary evil or have I missed something here?
I would say it's just evil. The problem is with the following part:
struct c {
union ab;
};
It's the same as writing:
struct c {
};
You can put any type and follow it with a ;
, like:
struct d {
int; float; unsigned long long; FILE *; some_other_type;
};
union ab
is just a type. The some_type ;
doesn't declare anything, nothing happens. The language grammar just allows you to write just a type as an expression without an identifier (ie. it's used in function declaration like void func(char*, int)
), but nothing happens and such expression has no meaning. Your struct c
is just empty, it has no members, it's undefined behavior.
trying to "reach" the union elements directly:
You can't access them, because they don't exists. There are no elements inside struct c
- it's empty.
You may duplicate code (possibly with a macro):
struct c {
union { // anonymous union
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
};
and access via:
struct c C;
printf("%d\n", C.a_st.a);