12

I'm reading some code and found something like the following:

typedef union {
    int int32;
    int boolean;
    time_t date;
    char *string;
    union {
        struct foo *a;
        struct foo *b;
        struct foo *c;
    };
} type_t;

From syntax point of view, the inner union {} can be removed and having *a, *b and *c directly inside the outer union {}. So what's the purpose the namelessly embedded union?

David Yaw
  • 27,383
  • 4
  • 60
  • 93
lang2
  • 11,433
  • 18
  • 83
  • 133
  • This is an interesting piece of C trivia, it's like NULL syntax. Potentially useful for an obfuscated code competition. – OregonTrail Mar 14 '14 at 16:00

3 Answers3

9

Unnamed union/struct inside another union/struct is a feature of C11, and some compiler extensions (e.g, GCC).

C11 §6.7.2.1 Structure and union specifiers

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.

The advantage of this feature is that one can access its unnamed union field easier:

type_t x;

To access the field a, you can simply use x.a. Compare with the code without using this feature:

typedef union {
    int int32;
    int boolean;
    time_t date;
    char *string;
    union u{      //difference in here
    struct foo *a;
    struct foo *b;
    struct foo *c;
    };
} type_t;

type_t x;

You need to use x.u.a.

Related: unnamed struct/union in C

Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • you mean a,b,c are 'direct' members of type_t in the original example ? – wap26 Mar 14 '14 at 13:28
  • 1
    @wap26 essentially yes, that's how the syntax reads for accessing them. – mah Mar 14 '14 at 13:30
  • 3
    But isn't it the same as removing the inner union? I mean, all the members have the same address in the end, right? – lang2 Mar 14 '14 at 13:46
  • 2
    @lang2 No it is not the same thing, because a b and c will share the same memory space. If you remove the union entirely, they will each get their own individual piece of memory. – Lundin Mar 14 '14 at 13:53
  • @lang2 I updated the answer, the linked related question may be helpful to you. – Yu Hao Mar 14 '14 at 15:09
  • 1
    @lang2 Ah yeah nevermind, for some reason I thought the outer union was a struct. – Lundin Mar 14 '14 at 15:21
  • Shouldn't the named union in the last code block be declared as `union { ... } u;`? – undur_gongor Jan 16 '15 at 11:28
7

I think the intended use-case is more “anonymous union inside a struct”, and the behavior of “anonymous union inside a union” being the same as a “flat” union is just an acceptable compromise for consistency.

Emmet
  • 6,192
  • 26
  • 39
0

Allows the same pointer to be called a, b or c. Maybe there is some legacy code that can't agree on what name to use.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101