Foundations — Type sizes — sizeof, platform dependency, stdint.h (int32_t etc.)
Before you can trust a single sentence of the parent note, you must be able to see what a "bit", a "byte", a "size", and a "type" actually are. This page builds each one from nothing, in the order they depend on each other, then shows you a map of how they feed the topic.
1. A bit — the single on/off switch
Picture it as a light switch on a wall. Down = , up = . That is the entire alphabet a computer has to write every number, letter, and image with.
Why the topic needs it: the whole idea of "how big is an int" is really "how many of these switches does it get." Sizes are counts of switches.
2. Counting with switches — why bits gives patterns
Line up several switches in a row. Each switch you add doubles the number of different arrangements, because for every old arrangement you now get two: "new switch off" and "new switch on."
Picture it: 1 switch → 2 pictures (). 2 switches → 4 pictures (). 3 switches → 8. The tree keeps splitting in two.
Why the topic needs it: this is exactly the derivation the parent uses to say an unsigned -bit number goes from to . If you don't feel why it doubles, the range formulas are just magic symbols.
3. A byte and the symbol
The parent note writes the guarantee char ≥ 8 bits. That symbol means "greater than or equal to".
Picture it as a fence with a gate: lets things through only up to a maximum height; the flat line under the arrow is the "equal is allowed too" part.
Why the topic needs it: C never says "char is exactly 8 bits." It says char ≥ 8. The is the legal loophole that lets a chip use bigger bytes. The whole "minimum width, not exact width" rule is built on this one symbol.
4. A type — the label that says how to read a box
Picture it as writing on the outside of a cardboard box: "8 slots, whole numbers only" vs "32 slots, can be negative." The bits inside are the same kind of switches; the label decides their meaning.
Why the topic needs it: char, short, int, long, long long are all just type labels, and this entire topic is about the fact that the label doesn't fix the box size — the platform does. Later the topic introduces labels like int32_t that do pin the size down; those are still just type labels, only stricter ones.
5. Signed vs unsigned — spending the top switch
Where does that lopsided range come from? Let's derive it instead of memorising it, using (8 patterns) as the picture.
We still have all switch patterns — nothing is thrown away. We just choose to read the top (leftmost) bit as a flag:
- Top bit → the number is the ordinary count of the remaining bits: values . For that is — exactly patterns.
- Top bit → the number is negative. These patterns are assigned to . For that is — again exactly patterns.
Why exactly half each way? Because the top bit has only two settings, and fixing it uses up one switch, leaving free switches = patterns per side. So the patterns split cleanly into two equal halves: non-negative and negative.
Why is there no "negative zero"? Zero is stored once, with all bits off (top bit ), so it counts as part of the non-negative half. That is why the positive side stops one short — it holds through (that's values including zero), while the negative side gets a full genuinely-negative values reaching all the way down to . The lopsided-looking is really "one zero shared into the top half."
Picture it as a ruler. Unsigned puts at the far-left end and counts right. Signed slides so the top-bit-off patterns () sit on the right and the top-bit-on patterns () sit on the left — same marks, just relabelled.
Why the topic needs it: sizeof returns an unsigned value (size_t), and int32_t vs uint32_t is exactly this choice. It also explains why INT32_MAX is (the top-bit-off half, minus the shared zero) but UINT32_MAX is (the whole range). Deeper: Two's complement & integer overflow.
6. Dividing to count — the ruler idea behind sizeof
Picture it as pouring a big jug () into small identical cups (): the number of full cups you can fill is .
Why the topic needs it: the parent's array-length trick
is just this division. It gives a count that never mentions how big an int is — which is the whole point of using it. (It breaks only when the array has "decayed" to a pointer — see Pointers and array decay.)
7. The size_t label and %zu
Picture it as a measuring tape whose numbers only go up (never negative), long enough to reach across the biggest object you could ever build.
Why the topic needs it: sizeof hands you back a size_t. Printing it with the wrong tag is a classic bug the parent warns about. More at size_t and ptrdiff_t and printf format specifiers.
How these foundations feed the topic
The figure below is the same map drawn as a picture: follow the arrows upward-to-downward and each idea is built from the ones pointing into it.
Walk it in words: a bit is one switch; stacking switches gives patterns and groups of eight give a byte; the pattern count plus the signed/unsigned choice produce the value ranges; a type is the label on the box; sizeof is the ruler that measures the box; size_t is where the ruler's reading is stored; and the exact-width int32_t idea grows out of both "type label" and "value range." All of these pour into the Type sizes topic itself.
Equipment checklist
Cover the right side and answer out loud.
What is a bit, in two states?
Why do bits give patterns?
What does count, and why the "minus one"?
What does the symbol mean, and where does the topic use it?
char ≥ 8 bits, a minimum not an exact size.What is a byte?
What is a type?
Why does the signed range split into equal halves?
Why is there no negative zero in two's complement?
Range of an unsigned -bit number?
What does C's integer / do with the remainder?
7/2 == 3, -7/2 == -3).Why doesn't truncation break sizeof a / sizeof a[0]?
What does sizeof return, and how do you print it?
size_t (unsigned size); print with %zu.