{"article":{"slug":"cs-flexible-integer-sizes-were-not-a-design-mistake","title":"C's Flexible Integer Sizes Were Not a Design Mistake","subtitle":null,"summary":"Gustavo Pezzi defends C’s platform-sized integers: how 12–60-bit machines shaped int, why minimum ranges beat fixed widths, and what Lua’s portable C still teaches.","content_type":"essay","language":"en","canonical_url":"https://pikuma.com/blog/c-integer-sizes-not-a-mistake","author":{"name":"Gustavo Pezzi","url":"https://pikuma.com","person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Pikuma","url":"https://pikuma.com","listing_slug":null,"listing":null},"topics":[{"name":"C","slug":"c","url":"https://listedarticles.com/topics/c"},{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Systems Programming","slug":"systems-programming","url":"https://listedarticles.com/topics/systems-programming"},{"name":"History","slug":"history","url":"https://listedarticles.com/topics/history"},{"name":"Hardware","slug":"hardware","url":"https://listedarticles.com/topics/hardware"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":486,"reading_minutes":2,"published_at":"2026-09-25T12:00:00.000Z","added_at":"2026-09-27T09:13:02.455Z","updated_at":"2026-09-27T09:13:02.455Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/cs-flexible-integer-sizes-were-not-a-design-mistake","markdown_url":"https://listedarticles.com/articles/cs-flexible-integer-sizes-were-not-a-design-mistake.md","example":false,"citation":"Gustavo Pezzi, Pikuma. \"C's Flexible Integer Sizes Were Not a Design Mistake.\" 25 Sept 2026. https://pikuma.com/blog/c-integer-sizes-not-a-mistake (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://pikuma.com/blog/c-integer-sizes-not-a-mistake"},"body_markdown":"# C's Flexible Integer Sizes were Not a Design Mistake\n\n**Author:** Gustavo Pezzi  \n**Published:** 25 September 2026  \n**Source:** [Pikuma](https://pikuma.com/blog/c-integer-sizes-not-a-mistake)\n\nWord sizes, strange machines, and why `int` was never meant to mean 32 bits. C's flexible integer types were not a design mistake. They were how the language achieved portability in a world of 12, 18, 36, and 60-bit computers.\n\n## Integers are Not 32-bits\n\nObserving `sizeof(int)` output 4 seems reasonable on modern machines — but on an old 386, `sizeof(int)` returned 2. Native C integer types (`char`, `int`, `short`, `long`) do not come with a guarantee of how many bytes they occupy.\n\nSince we usually want fixed sizes, we suggest `<stdint.h>` types such as `int8_t`, `uint32_t`, etc. (C99).\n\n## Are Non-Fixed Integer Sizes a Design Mistake?\n\nA fairly common take is that C's platform-dependent integer types were a design mistake. An `int` is 16 bits on one machine and 32 on another; `long` is 64 bits on Linux but 32 on 64-bit Windows. But judging a 1970s design by 2020s conditions misses the point.\n\n## The World Before 8-bit Bytes Won\n\nMachine word sizes in the 1960s–70s included PDP-8 (12-bit), PDP-7 (18-bit), PDP-11 (16-bit), PDP-10 (36-bit), CDC 6600 (60-bit), Cray-1 (64-bit), and many others. Characters weren't consistent either (6-bit, 7-bit ASCII, 9-bit bytes, EBCDIC).\n\n## Where C's Types Came From\n\nBCPL and B were typeless — one machine word. The PDP-11 was byte-addressed; Dennis Ritchie describes how B's model fit poorly. C's `char` gave you the byte; `int` kept the spirit of BCPL's word — the natural integer of the machine. Even today, C11 §6.2.5 says a plain `int` has the natural size suggested by the architecture.\n\n## C Escapes the PDP-11\n\nK&R (1978) already listed type sizes on DEC PDP-11, Honeywell 6000, IBM 370, and Interdata 8/32 — including 16-bit, 32-bit, and 36-bit ints, and 8-bit and 9-bit chars.\n\n## Why Flexible Sizes Were Useful\n\nFixed 32-bit `int` would have been costly on 16-bit machines (two instructions per op), wasteful on 36-bit machines, and painful on ones'-complement and word-addressed systems. ANSI C standardized *minimum ranges*, not exact sizes.\n\n## A Case Study in Portable C: Lua\n\nLua's “Clean C” approach asks the compiler what it has via `<limits.h>` and chooses types based on guaranteed ranges — e.g. `LUAI_IS32INT`, instruction types that are “at least 4 bytes,” and `CHAR_BIT`-aware packing in `string.pack`.\n\n## Being Fair: What Hurt\n\nPeople assumed sizes; the LP64 vs LLP64 split hurt; `<stdint.h>` arrived late. Exact-width types remain optional when the machine lacks that width.\n\n## How Modern Languages Differ\n\nJava, Rust, Zig, Go, and Swift pin down widths because the architecture wars were over — yet many still keep a natural/platform-sized integer (`isize`/`usize`, Go `int`, Swift `Int`).\n\n## Conclusion\n\nFixed integer sizes would have made C slow or impractical on many 1970s machines. Leaving sizes open, backed by guaranteed minimum ranges, made C run nearly everywhere. It wasn't a mistake. Portability was the whole point.\n","body_html":"<h1 id=\"c-s-flexible-integer-sizes-were-not-a-design-mistake\">C&#39;s Flexible Integer Sizes were Not a Design Mistake</h1>\n<p><strong>Author:</strong> Gustavo Pezzi<br />\n<strong>Published:</strong> 25 September 2026<br />\n<strong>Source:</strong> <a href=\"https://pikuma.com/blog/c-integer-sizes-not-a-mistake\" rel=\"nofollow ugc noopener\">Pikuma</a></p>\n<p>Word sizes, strange machines, and why <code>int</code> was never meant to mean 32 bits. C&#39;s flexible integer types were not a design mistake. They were how the language achieved portability in a world of 12, 18, 36, and 60-bit computers.</p>\n<h2 id=\"integers-are-not-32-bits\">Integers are Not 32-bits</h2>\n<p>Observing <code>sizeof(int)</code> output 4 seems reasonable on modern machines — but on an old 386, <code>sizeof(int)</code> returned 2. Native C integer types (<code>char</code>, <code>int</code>, <code>short</code>, <code>long</code>) do not come with a guarantee of how many bytes they occupy.</p>\n<p>Since we usually want fixed sizes, we suggest <code>&lt;stdint.h&gt;</code> types such as <code>int8_t</code>, <code>uint32_t</code>, etc. (C99).</p>\n<h2 id=\"are-non-fixed-integer-sizes-a-design-mistake\">Are Non-Fixed Integer Sizes a Design Mistake?</h2>\n<p>A fairly common take is that C&#39;s platform-dependent integer types were a design mistake. An <code>int</code> is 16 bits on one machine and 32 on another; <code>long</code> is 64 bits on Linux but 32 on 64-bit Windows. But judging a 1970s design by 2020s conditions misses the point.</p>\n<h2 id=\"the-world-before-8-bit-bytes-won\">The World Before 8-bit Bytes Won</h2>\n<p>Machine word sizes in the 1960s–70s included PDP-8 (12-bit), PDP-7 (18-bit), PDP-11 (16-bit), PDP-10 (36-bit), CDC 6600 (60-bit), Cray-1 (64-bit), and many others. Characters weren&#39;t consistent either (6-bit, 7-bit ASCII, 9-bit bytes, EBCDIC).</p>\n<h2 id=\"where-c-s-types-came-from\">Where C&#39;s Types Came From</h2>\n<p>BCPL and B were typeless — one machine word. The PDP-11 was byte-addressed; Dennis Ritchie describes how B&#39;s model fit poorly. C&#39;s <code>char</code> gave you the byte; <code>int</code> kept the spirit of BCPL&#39;s word — the natural integer of the machine. Even today, C11 §6.2.5 says a plain <code>int</code> has the natural size suggested by the architecture.</p>\n<h2 id=\"c-escapes-the-pdp-11\">C Escapes the PDP-11</h2>\n<p>K&amp;R (1978) already listed type sizes on DEC PDP-11, Honeywell 6000, IBM 370, and Interdata 8/32 — including 16-bit, 32-bit, and 36-bit ints, and 8-bit and 9-bit chars.</p>\n<h2 id=\"why-flexible-sizes-were-useful\">Why Flexible Sizes Were Useful</h2>\n<p>Fixed 32-bit <code>int</code> would have been costly on 16-bit machines (two instructions per op), wasteful on 36-bit machines, and painful on ones&#39;-complement and word-addressed systems. ANSI C standardized <em>minimum ranges</em>, not exact sizes.</p>\n<h2 id=\"a-case-study-in-portable-c-lua\">A Case Study in Portable C: Lua</h2>\n<p>Lua&#39;s “Clean C” approach asks the compiler what it has via <code>&lt;limits.h&gt;</code> and chooses types based on guaranteed ranges — e.g. <code>LUAI_IS32INT</code>, instruction types that are “at least 4 bytes,” and <code>CHAR_BIT</code>-aware packing in <code>string.pack</code>.</p>\n<h2 id=\"being-fair-what-hurt\">Being Fair: What Hurt</h2>\n<p>People assumed sizes; the LP64 vs LLP64 split hurt; <code>&lt;stdint.h&gt;</code> arrived late. Exact-width types remain optional when the machine lacks that width.</p>\n<h2 id=\"how-modern-languages-differ\">How Modern Languages Differ</h2>\n<p>Java, Rust, Zig, Go, and Swift pin down widths because the architecture wars were over — yet many still keep a natural/platform-sized integer (<code>isize</code>/<code>usize</code>, Go <code>int</code>, Swift <code>Int</code>).</p>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>Fixed integer sizes would have made C slow or impractical on many 1970s machines. Leaving sizes open, backed by guaranteed minimum ranges, made C run nearly everywhere. It wasn&#39;t a mistake. Portability was the whole point.</p>","headings":[{"level":1,"text":"C's Flexible Integer Sizes were Not a Design Mistake","id":"c-s-flexible-integer-sizes-were-not-a-design-mistake"},{"level":2,"text":"Integers are Not 32-bits","id":"integers-are-not-32-bits"},{"level":2,"text":"Are Non-Fixed Integer Sizes a Design Mistake?","id":"are-non-fixed-integer-sizes-a-design-mistake"},{"level":2,"text":"The World Before 8-bit Bytes Won","id":"the-world-before-8-bit-bytes-won"},{"level":2,"text":"Where C's Types Came From","id":"where-c-s-types-came-from"},{"level":2,"text":"C Escapes the PDP-11","id":"c-escapes-the-pdp-11"},{"level":2,"text":"Why Flexible Sizes Were Useful","id":"why-flexible-sizes-were-useful"},{"level":2,"text":"A Case Study in Portable C: Lua","id":"a-case-study-in-portable-c-lua"},{"level":2,"text":"Being Fair: What Hurt","id":"being-fair-what-hurt"},{"level":2,"text":"How Modern Languages Differ","id":"how-modern-languages-differ"},{"level":2,"text":"Conclusion","id":"conclusion"}]}}