All Posts

Mastering Union Data Types in C: A Deep Dive

Union in C

Union Definition and How It Works

A union in C is a data type that allows storing multiple fields of different types in the same memory location. By having its fields overlap at the same memory address, a union optimizes memory usage.

Let’s take below example of an union definition:

// Anonymous union
union UnionType{
    char alpha;
    int num;
} UnionType;

From a hardware perspective, the alpha and num elements within the union will overlap, sharing the same memory address.

union elements overlapping the same memory address

In this union definition, the size of the union is determined by its largest element. In the example above, the largest element is num, which is an integer and occupies 4 bytes.

Below is an example of how to access union elements and the resulting outcomes:

// Anonymous union
union UnionType{
    char alpha;
    int num;
} UnionType;

union UnionType ex;
ex.alpha = 'C';
ex.num = 0x12345678;

printf("%c",ex.alpha); // --> result will be 'x' (code hex 0x78)
printf("%d",ex.num);   // --> result will be '305.419.896' (code hex is 0x12345678)

The alpha element has been overwritten by num because both elements overlap and share the same memory address.

union fields overwritten

---

Union as C Structure Element

A union can be combined with a structure in C by including the union as a new data type within the defined structure.

// Anonymous union
union UnionType{
    char alpha;
    int num;
} UnionType;

// First type of declaration of our struct
// dictionary structure
typedef struct dict {
  int val;
  UnionType element;
} dict; // sizeof(dict) --> 8 bytes

// Second type of declaration of our struct
// dictionary structure
typedef struct dict {
  int val;
  char alpha;
  int num;
} dict; // sizeof(dict) --> 9 bytes

In the example above, we’ve added a union-based data type to our C structure. By doing this, we avoid wasting memory space, resulting in a total structure size of 8 bytes: 4 bytes for the integer val and 4 bytes for the UnionType element. Since alpha and num share the same memory address, they do not require additional space.

If we don’t use a union, we would need to add separate elements for alpha (1 byte) and num (4 bytes). This would increase the overall size of the structure to 9 bytes instead of 8 bytes (4 bytes for the integer val, 1 byte for the character alpha, and 4 bytes for the integer num).