5.1.3 · D1C Programming

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

2,081 words9 min readBack to topic

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.

bit = one on off switch

N bits give 2 to the N patterns

byte = group of 8 bits

value ranges 0 to 2^N minus 1

signed vs unsigned

type = label on a box of bits

sizeof measures the box

size_t holds the measurement

stdint exact width int32_t

Type sizes topic


Equipment checklist

Cover the right side and answer out loud.

What is a bit, in two states?
A single switch that is either (off) or (on).
Why do bits give patterns?
Each added switch doubles the arrangements, so it is multiplied by itself times.
What does count, and why the "minus one"?
The largest unsigned value, minus one because counting starts at .
What does the symbol mean, and where does the topic use it?
"Greater than or equal to"; C guarantees char ≥ 8 bits, a minimum not an exact size.
What is a byte?
A group of bits (8 on normal machines) holding patterns.
What is a type?
A label saying how many bits a box has and how to read the pattern.
Why does the signed range split into equal halves?
Fixing the top bit as a sign flag leaves free bits = patterns on each side.
Why is there no negative zero in two's complement?
Zero is stored once in the non-negative half, so the positive side stops at while the negative side reaches .
Range of an unsigned -bit number?
to .
What does C's integer / do with the remainder?
Throws it away, truncating toward zero (7/2 == 3, -7/2 == -3).
Why doesn't truncation break sizeof a / sizeof a[0]?
The total size is an exact multiple of one element's size, so the remainder is .
What does sizeof return, and how do you print it?
A size_t (unsigned size); print with %zu.
Why is size_t unsigned?
Sizes and counts are never negative, so it only needs non-negative values.