Or rather, unnamed unions:
struct my_struct {
int a;
union {
int b;
double c;
void* d;
};
int e;
} foo, *bar;
You can then reference t as foo,a, foo.b, foo.c, foo.d, and foo.e.
Without it the union must be named:
struct my_struct {
int a;
union {
int b;
double c;
void* d;
} u;
int e;
} foo, *bar;
and referenced as foo.a, foo.u.b, foo.u.c, foo.u.d, and foo.e. Or the less useful bar->a, bar->u.b, bar->u.c, bar->u.d, and bar->e. (And who has NOT gotten confused in a complex structure of structures with pointers and such?)
Using bar->a, bar->b, bar->c, bar->d, and bar->e can make code far more legible.
Often a data structure will have a header that tells you what type it is, followed by a union of available types - so you might have a "type" field that specifies if the following data is an int, for a float, or a double, or a string and then followed by a union of all them.
Or because it's a Microsoft extension, Windows makes use of "size" parameters in structs to be binary compatible. So you might declare a struct, then the first parameter is sizeof(struct), which is used so if the API internally adds more elements, it can switch back to older behavior when given a shorter struct so old programs using the old struct still work with APIs that could take either version.