One classic is to represent a value of "unknown" type, as in the core of a simplistic virtual machine:
typedef enum { INTEGER, STRING, REAL, POINTER } Type;
typedef struct
{
Type type;
union {
int integer;
char *string;
float real;
void *pointer;
} x;
} Value;
Using this you can write code that handles "values" without knowing their exact type, for instance implement a stack and so on.
Since this is in (old, pre-C11) C, the inner union must be given a field name in the outer struct
. In C++ you can let the union
be anonymous. Picking this name can be hard. I tend to go with something single-lettered, since it is almost never referenced in isolation and thus it is always clear from context what is going on.
Code to set a value to an integer might look like this:
Value value_new_integer(int v)
{
Value v;
v.type = INTEGER;
v.x.integer = v;
return v;
}
Here I use the fact that struct
s can be returned directly, and treated almost like values of a primitive type (you can assign struct
s).