union initialisation

2019-04-07 06:14发布

问题:

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)?

回答1:

You would want to do this:

a temp = {i: w};

That should work for both gcc and g++.



回答2:

In C99 you can do this:

a temp = { .i=w };


回答3:

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 );


回答4:

You can initialise the integer member like this:

a temp = {
  .i = w
};


标签: c++ c unions