Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seeking C Union clarity

Tags:

c

unions

typedef union {
    float flts[4];
    struct {
        GLfloat r;
        GLfloat theta;
        GLfloat phi;
        GLfloat w;
    };
    struct {
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;
    };
} FltVector;

Ok, so i think i get how to use this, (or, this is how i have seen it used) ie.

FltVector fltVec1 = {{1.0f, 1.0f, 1.0f, 1.0f}};
float aaa = fltVec1.x;
etc.

But i'm not really groking how much storage has been declared by the union (4 floats? 8 floats? 12 floats?), how? and why? Also why two sets of curly braces when using FltVector {{}}?

Why use a union at all? Why not do..

   struct FltVector {
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;
   }

?

Any pointers much appreciated (sorry for the pun)

like image 416
hooleyhoop Avatar asked May 20 '10 11:05

hooleyhoop


3 Answers

if sizeof(GLfloat) == sizeof(float) then, 4 floats have been allocated.

flts[0], r and x will all refer to the same piece of memory here.

In a union, every different variable declared in the union refers to the same piece of memory.

Here we have 3 variables, 2 structs and an array, and each of them start at the same point in memory.

like image 63
Salgar Avatar answered Nov 12 '22 01:11

Salgar


A union allows you to “recycle” the same area of memory for different types of variables. Generally the union takes as much storage as its single largest member, in this case probably 4 floats. You can check with sizeof.

In this case the union is probably used to provide 1) alternative names for the same floats in the struct (e.g. x and r share the same memory), and 2) access to the same four floats as an array (e.g. x and flts[0] share the same memory). Sometimes unions are used in various “hacks”, usually non-portable, to access the internals of some data type e.g. the individual bytes in an integer in the machine order.

like image 5
Arkku Avatar answered Nov 12 '22 01:11

Arkku


A few questions there :)

@Arkku is right about the size. Alignment can also play a part, but probably not here.

Why this is true is that at any given time the union only holds one of the possible values. For this reason it's common to have the union in a struct alongside something which identifies which value is valid (sometimes called a discriminated union or scrim).

One pair of braces is for the union, and the other for the array initalizer.

like image 2
pdbartlett Avatar answered Nov 12 '22 02:11

pdbartlett