Just for clarifications about anonymous struct
or anonymous union
.
C11
6.7.2.1 Structure and union specifiers
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.
C99 There are no anonymous struct or union
Simplified: Type-specifier Identifier {
Declaration-list }
Tags ;
- Type-specifier:
struct
or union
;
- Identifier: optional, your custom name for the
struct
or union
;
- Declaration-list: members, your variables, anonymous
struct
and anonymous union
- Tags: optional. If you have a
typedef
in front of the Type-specifier, the Tags are alias and not Tags.
It is a anonymous struct
or anonymous union
only if it have no identifier and no tag, and exist inside another struct
or union
.
struct s {
struct { int x; }; // Anonymous struct, no identifier and no tag
struct a { int x; }; // NOT Anonymous struct, has an identifier 'a'
struct { int x; } b; // NOT Anonymous struct, has a tag 'b'
struct c { int x; } C; // NOT Anonymous struct
};
struct s {
union { int x; }; // Anonymous union, no identifier and no tag
union a { int x; }; // NOT Anonymous union, has an identifier 'a'
union { int x; } b; // NOT Anonymous union, has a tag 'b'
union c { int x; } C; // NOT Anonymous union
};
typedef
hell: if you have a typedef
the tag part is not a tag anymore, it is alias for that type.
struct a { int x; } A; // 'A' is a tag
union a { int x; } A; // 'A' is a tag
// But if you use this way
typedef struct b { int x; } B; // 'B' is NOT a tag. It is an alias to struct 'b'
typedef union b { int x; } B; // 'B' is NOT a tag. It is an alias to union 'b'
// Usage
A.x = 10; // A tag you can use without having to declare a new variable
B.x = 10; // Does not work
B bb; // Because 'B' is an alias, you have to declare a new variable
bb.x = 10;
The example bellow just change struct
for union
, work the same way.
struct a { int x; }; // Regular complete struct type
typedef struct a aa; // Alias 'aa' for the struct 'a'
struct { int x; } b; // Tag 'b'
typedef struct b bb; // Compile, but unusable.
struct c { int x; } C; // identifier or struct name 'c' and tag 'C'
typedef struct { int x; } d; // Alias 'd'
typedef struct e { int x; } ee; // struct 'e' and alias 'ee'
-std=c99
silently, without any errors and warnings. – Pythagoras