5.1.3 · D2C Programming

Visual walkthrough — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

1,686 words8 min readBack to topic

Step 1 — One bit is one switch

WHAT we do: draw the smallest possible piece of memory — one switch — and list everything it can be.

WHY: every integer in C is built out of bits stacked side by side. If we understand one switch completely, the rest is just repetition. We must not use the word "byte" or "" yet — we have not earned them.

PICTURE: the switch below has exactly two positions. Two positions means two distinct numbers it can represent. That "2" is the seed of the whole derivation.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 2 — Each extra switch doubles the count

WHAT we do: go from 1 switch to 2 switches and count arrangements by hand.

WHY: we want a formula for "how many numbers fit in switches", and the honest way to get it is to watch the count grow and spot the pattern — not to assert from thin air.

PICTURE: the tree branches. 1 switch → leaves. 2 switches → leaves. 3 switches → leaves.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 3 — Turn patterns into unsigned numbers

WHAT we do: label the patterns with the numbers

WHY: we have a count of patterns (), but a count is not yet a range of values. To get a range we must decide which pattern means which number. The simplest rule: start at and go up.

PICTURE: below, the 3-bit patterns are laid on a number line. Since we start at , the largest value is one less than the count.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 4 — Split the patterns to make signed numbers

WHAT we do: take the same patterns and re-label half of them as negatives.

WHY: computers need negative numbers too. But we only have patterns total — we cannot invent more. So negatives must come out of the same budget. Cutting in half is the natural split.

PICTURE: the ring of patterns is sliced down the middle. The non-negative half runs ; the negative half runs .

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 5 — Plug in

WHAT we do: stop talking about in general and set — the width int32_t promises.

WHY: int32_t is defined to be exactly 32 bits, signed, two's complement (this is the guarantee the parent note relies on). Everything from Steps 3–4 applies with .

PICTURE: 32 switches in a row, top bit tinted as the sign region, and the two limit numbers pinned to each end.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 6 — Edge case: what happens at the top?

WHAT we do: stand on the maximum value and add 1.

WHY: a derivation is not finished until we know what happens at the boundary. The ring from Step 4 makes this obvious: past the last pattern you land back at the first neighbour.

PICTURE: UINT32_MAX + 1 wraps to 0 (defined, modular). INT32_MAX + 1 wraps to INT32_MIN — for signed types this is undefined behaviour in C, a trap, not a feature.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

Step 7 — Degenerate case: why plain int won't sign the contract

WHAT we do: replace int32_t with plain int and re-run Step 5.

WHY: this is the whole reason stdint.h exists. The C standard only fixes a minimum for int (16 bits) and an ordering, not an exact . So the number in our formula is not pinned — it changes with the platform's ABI.

PICTURE: the same 32-slot ruler, but now the box width is a dashed "?" — it could be 16 slots on old hardware, 32 on your laptop. The formula still holds; we just don't know which to feed it.

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

The one-picture summary

Figure — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)

The whole chain in one frame: 1 switch = 2 states → switches = patterns → count from 0 (unsigned) or split in half (signed) → set → read off the limits → and int32_t is the only spelling that fixes everywhere.

Recall Feynman retelling — explain it to a friend in plain words

Picture a row of light switches. One switch = 2 choices. Add a switch and every old choice doubles, so switches give different pictures. If we just number those pictures starting at zero, the biggest number is one less than the count — that's an unsigned box, to . If we want negatives too, we slice the pictures into two equal piles: one pile positive, one pile negative. Zero sits in the positive pile, so the negative pile is one deeper — that's why a signed box goes from to . Now bolt to and you get up to , or to unsigned. Push past the top and you loop back to the bottom like an odometer rolling over. The catch: plain int never tells you what is — it might be 16 switches on a tiny computer. Only int32_t writes the 32 right on the box, so two different computers can mail each other numbers that line up perfectly.


Connections