Search code examples
cvectorstructsseunions

How to use a C union to equate multiple named variables and another, larger named variable?


Let's say I have a struct

struct vector_struct {
    float x;
    float y;
    float z;
} vector;

I would like to be able to address the x, y, and z values as vector.x etc. which the above code allows me to do. However, in order to facilitate fast arithmetic with SSE SIMD instructions in an explicit way, I would like to do the following:

union vector_union {
    struct vector_struct float_values;
    __m128d packed_values;
} vector;

Now, if I want to do SIMD instructions on the vector, I can just use vector.packed_values as an argument to various SIMD instructions (like multiplication). However, this looks very ugly, as if I wanted the value of x, I would have to write

foo = vector.float_values.x

instead of just

foo = vector.x

So then, my question is if there is any way to make a union that associates multiple named variables with another single named variable. Something like

union vector_union {
    float values[3];
    __m128d packed_values;
} vector;

except where vector.values[0] can be referred to as vector.x, vector.values[1] can be referred to as vector.y, etc.


Solution

  • As of C2011, you can use an anonymous struct member in your union,

    union vector_union {
        struct {
            float x, y, z;
        };
        __m128d packed;
    } vector;
    

    and then you can use vector.x etc. to access the components, and vector.packed_values to use the SSE instructions. Note, however, that the standard doesn't guarantee that the structmember is packed. (But normally, the compiler will pack it.)

    If the compiler doesn't support C2011, it may offer anonymous structs as an extension.