7

I'm attempting to globally initialise a union as in the following example:

#include <cstdio>

typedef union {
    char t[4];
    int i;
} a;

enum {
    w = 5000,
    x,
    y,
    z
};

a temp = {w};
int main() {
    printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],temp.t[3],temp.i);
    return 0;
}

However, if you run the code, you'll note that neither of temp.i or temp.t[...] actually give the correct item i initialised the union with. I'd imagine this would be avoided if I could manually initialise the integer member, but unfortunately I can't. I also can't change the ordering of elements within the struct (swapping the int and char order initialises everything properly) - they're actually provided by an external library. My question is this: how can I set the integer member of the structure globally, rather than the char[4] member (or, in this case, just the first element of the char[])?

EDIT: Also, is there a strictly-c++ solution to this problem? i.e. one where named struct initialisation doesn't work (because it doesn't exist in the language)?

timrau
  • 22,578
  • 4
  • 51
  • 64
Ben Stott
  • 2,218
  • 17
  • 23

4 Answers4

10

In C99 you can do this:

a temp = { .i=w };
Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
7

You would want to do this:

a temp = {i: w};

That should work for both gcc and g++.

evgeny
  • 2,564
  • 17
  • 27
7

In C99 you can do use named initialization as in:

a x = { .i = 10 };

There are some suggestion for using the non-standard gcc extension, but I would avoid it if coding C :

a x = { i : 10 };

You can use a function to initialize:

inline a initialize( int value ) { // probably choose a better name
   a tmp;
   tmp.i = value;
   return a;
}

and then use:

a x = initialize( 10 );

The compiler will optimize the copies away.

If you are doing C++, you can provide a constructor for your union type:

/*typedef*/ union u {           // typedef is not required in general in C++
    char bytes[sizeof(int)];
    int i;
    u( int i = 0 ) : i(i) {}
} /*u*/;

u x( 5 );
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • The problem is I can't modify the union itself, otherwise I'd just rearrange the elements and be done with it. I do like the inline approach, though. – Ben Stott May 28 '11 at 11:31
5

You can initialise the integer member like this:

a temp = {
  .i = w
};
Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130