Unions – ew.
As primarily a C++ programmer, I used to shy away from code that contained this kind of black magic. However, unions are actually very cool things and are really not that scary or weird.
A union is basically a variable. But instead of being an int, or a float, or a double, a union can actually be any one of these things at a given point in time.
What? That doesn’t make any sense!
Wait – let me illustrate with an example.
The code below contains a union declaration at the top. Unions are declared just like structs, but instead of containing ALL the variables listed, a union only contains enough space for the largest one.
So in my example, where the union contains an int and a char – how big do you think will it be?
That’s right, it will be a single variable the same size as an int, because an int is larger than a char.
Storing and accessing union data is done just like it is with a struct:
/* Incoming data - could come from a variety of sources: */
a.symbol = 'x';
a.number = 120;
/* output last type in (int) */
printf("Variable a is set to %d\n", a.number);
Okaaay… but how do you know what it is when it can be multiple things?
Good question. You can’t actually tell what is inside a union, but the rule is that whatever you put in last, will be what you get out, and it is YOUR responsibility to remember what it was.
The best way to do this is with a variable that you update to contain the correct type (use an enum of INT, FLOAT, etc.)
If you access a union using a type that isn’t the same as the one last stored, what you get back is undefined.
Unions are really useful when you want to save storage space (especially good in embedded programming), or if you are receiving data that may arrive in different types (but which is essentially being used for the same purpose).
See? Not so scary after all.