Here's one use. When working with unions, it's implementation defined what you'll get when reading a union member that wasn't last written to. But, in the case of structures, you can inspect the common initial sequence of fields. Here's an example to illustrate:
#include <assert.h>
struct S1 {
int type;
char value;
};
struct S2 {
int type;
float value;
};
union U {
struct S1 s1;
struct S2 s2;
};
int main() {
union U un;
un.s1.type = 1;
un.s1.value = 'c';
assert(un.s2.type == 1);
}
As you can see above, it is guaranteed by the C standard that whatever I write to un.s1.type I can then read from un.s2.type. So far so good. But there's a problem if I try to do something like this instead:
union U {
struct S1 s1;
int type;
};
Now there is no guarantee. We can't read un.s1.type from un.type under the protection of the standard. But hope is not lost, we can just make it a field of a structure again, an anonymous structure, like so:
union U {
struct S1 s1;
struct {
int type;
};
};
The fields of an anonymous structure are "injected" into the enclosing structure or union, so we may refer to type by accessing un.type. And now were are back to the warm embrace of the standard. Since now we again have two structures with a common initial sequence of fields.