8

I have a struct:

typedef struct _n
{
    int type;
    union {
        char *s;
        int i;
    };
} n;

When I try to assign a compound literal, like:

node n1 = {1, 0};
node n2 = {2, "test"};

gcc gives me some warnings such as:

warning: initialization makes pointer from integer without a cast
warning: initialization from incompatible pointer type

Well, it's clear that the compiler isn't sure about me just assigning a value to a possibly ambiguous type. However, even if I try to specify more precisely:

node n0 = {type: 1, i: 4};

I get:

error: unknown field ‘i’ specified in initializer

I have read that if I put (union <union name>) before i: then it may work. However, I prefer having an anonymous union. Is there a way to do it?

timrau
  • 22,578
  • 4
  • 51
  • 64
Steve
  • 1,849
  • 2
  • 19
  • 19

1 Answers1

9

Anonymous unions are not standard C -- they are a compiler extension. I would strongly recommend giving the union a name. If you insist on using an anonymous union, then you can only give an initializer for the first element of it:

node n0 = {1, 0};  // initializes `s' to 0

When compiled with -Wall -Wextra -pedantic, gcc gave me the warning "missing braces around initializer", which is a valid warning. The initializer should actually be specified like this:

node n0 = {1, {0}};  // initializes `s' to 0

Now this only gives a warning that "ISO C doesn't support unnamed structs/unions".

If you give the union a name, then you can use a C99 feature called designated initializers to initialize a specific member of the union:

typedef struct
{
    int type;
    union {
        char *s;
        int i;
    } value;
} node;

node n0 = {1, { .s = "string" }};
node n1 = {2, { .i = 123 }};

You need the union to have a name; otherwise, the compiler will complain about the designated initializer inside it.

The syntax you were trying to use node n0 = {type: 1, i: 4} is invalid syntax; it looks like you were trying to use designated initializers.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • It surprised me the first time I saw it, but to GCC that's actually legal (though deprecated) designated initializer syntax. – ephemient Dec 11 '09 at 05:39
  • that (i guess deprecated) initializer syntax i got from reading some kernel module code.. 'fops' structures are often written that way. i'll switch to the C99 way now. Too bad about anonymous unions, I didn't know they were not standard, thanks for clearing that up for me. – Steve Dec 11 '09 at 13:58
  • Are you sure that there is a `;` after `123` or `"string"` ? It doesn’t compile for me with it. It compiles without it. – chmike Dec 15 '20 at 09:55
  • @chmike: Whoops, not sure why I did that 11 years ago—you're right, there should not be semicolons in there. Fixed now. – Adam Rosenfield Dec 15 '20 at 16:21