This example shows how a programmer can use an extra variable which stores the type of the latest write access to make sure that the proper read access is done.
union number n;
enum { CHAR, INT, FLOAT, DOUBLE } accessType;
n.i = 10;
accessType = INT;
// on retrieval:
switch (accessType) {
case CHAR:
// get n.c
break;
case INT:
// get n.i
break;
case FLOAT:
// get n.f
break;
case DOUBLE:
// get n.d
break;
}
In many years of kernel and other c-hacking I have found little use for unions....
Unions compared to regular structs simply save some memory because the allocate enough memory for the largest type defined within the union - in the above case "double" and use this space for every type in the union.