5.1.24C Programming

Unions — overlapping memory

1,591 words7 min readdifficulty · medium

WHAT is a union?

union Data {
    int   i;     // 4 bytes
    float f;     // 4 bytes
    char  c[4];  // 4 bytes
};

Contrast with a struct:

Feature struct union
Memory sum of all members (+padding) size of largest member
Members live all simultaneously only one at a time
Use case bundle related data save space / reinterpret bytes

WHY is its size the largest member?


Figure — Unions — overlapping memory

HOW the bytes overlap (the key picture)


A practical use: tagged union (safe pattern)

struct Variant {
    enum { INT, FLOAT, STR } tag;   // who lives in the room now?
    union { int i; float f; char *s; } val;
};

WHY: there is no runtime flag inside a union telling you the active member. The tag is your bookkeeping so you only read what you last wrote.



Recall Feynman: explain to a 12-year-old

Imagine one whiteboard. You can write a number, OR a word, OR a drawing — but only one thing fits because it's the same board. If you write a word over your number, the number is gone. A union is that single whiteboard shared by different kinds of "writing." A struct, by contrast, is a notebook with a separate page for each thing. The board is exactly as big as the biggest thing you might write.


Flashcards

What is the defining property of a union's members?
They all share the same memory (start at offset 0), so only one is valid at a time.
How is the size of a union determined?
It equals the size of its largest member, rounded up to satisfy alignment.
In a struct, how is size determined vs a union?
struct = sum of members (+padding); union = size of largest member (+padding).
What happens to other members when you write one union member?
Their bytes are overwritten/reinterpreted — reading them now gives meaningless data.
Does reading a different union member perform a type conversion?
No — it reinterprets the raw bit pattern (type punning), not an arithmetic conversion.
What is a tagged union and why is it needed?
A struct holding the union plus an enum tag recording the active member, because a union itself doesn't remember which member is live.
For union { char c; int i; double d; }, what is sizeof?
8 (size of the largest member, double, already 8-aligned).
With little-endian and u.i = 65, what does u.c[0] give?
'A' (0x41), the lowest-order byte of 65.

Connections

  • Structs — separate memory for each member
  • Memory alignment and padding
  • Endianness — byte order
  • Type punning and bit-level reinterpretation
  • Enums (used for the tag in tagged unions)
  • sizeof operator

Concept Map

members at

so size is

adjusted by

means

leads to

enables

depends on

goal

contrasted with

size = sum of members

union type

shared memory offset 0

size = largest member

align rounds up size

only one member at a time

writing overwrites others

type punning

little-endian byte order

saves memory

struct: separate memory

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, union ka matlab simple hai: ek hi memory ka tukda jise saare members share karte hain. struct mein har member ka apna alag ghar hota hai (isliye size = sab members ka sum), lekin union mein sab roommates ek hi kamre mein rehte hain — sabhi offset 0 se start hote hain. Isliye union ka size hamesha uske sabse bade member ke barabar hota hai (alignment padding ke saath).

Sabse important baat: ek time pe sirf ek member valid hota hai. Jab tum d.f = 3.14 likhte ho, to wahi bytes overwrite ho jaate hain, aur agar tum phir d.i padho to garbage milega — kyunki ab un bytes mein float ka bit pattern pada hai, int ka nahi. Ye koi conversion nahi hota, sirf same bytes ko alag tarah se "padhna" hai (isko type punning kehte hain).

Ek bahut common galti: log sochte hain d.i = 65 ke baad d.f padhne se 65.0 milega. Galat! Bits same hote hain par interpretation alag — int 65 aur float 65.0 ke bit patterns bilkul alag hote hain. Value convert karni ho to (float)d.i cast karo.

Real life mein union ka use memory bachane ke liye aur tagged union banane ke liye hota hai — ek struct mein union + ek enum "tag" rakho jo bataye abhi kaunsa member active hai, kyunki union khud kuch yaad nahi rakhta. Bas yahi core idea hai: ek room, ek waqt mein ek hi cheez, size = sabse bada member.

Go deeper — visual, from zero

Test yourself — C Programming