logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·30.10.26
← Back to news

C's Flexible Integer Sizes Were Not a Design Mistake

Original article
pikuma.com|38 points|62 comments|by ibobev|Sep 25, 2026

C's Flexible Integer Sizes Were Not a Design Mistake

The Core Thesis: int was never intended to be a synonym for "32 bits." Instead, C's adaptable integer types were the primary mechanism for achieving portability across a fragmented landscape of 12, 18, 36, and 60-bit architectures.


The Beginner's Hurdle

At our school, we specialize in retro hardware and vintage game consoles. Consequently, we often guide developers who are just starting their journey with the C programming language. Many of these students transition from high-level languages such as:

  • Python
  • JavaScript
  • Java
  • C#
  • Swift

It doesn't take long for these newcomers to realize that the assumptions they held in their primary languages are guaranteed do not apply in C. A frequent point of confusion is the fundamental question: "Exactly how many bits does this variable occupy in memory?"

The sizeof Revelation

A pivotal moment for any C student is mastering the sizeof operator. On a modern machine, seeing the following output is standard:

printf("%zu", sizeof(int)); 
// Output: 4

sizeof int 4 bytes

However, I often share my own experience: when I first learned to code on an old 386 machine, the result was different:

printf("%zu", sizeof(int)); 
// Output: 2

sizeof int 2 bytes

This leads to a critical realization: native C integer types have no fixed size. Types like char, int, short, and long provide no absolute guarantee regarding their byte count.

Solving the Ambiguity with STDINT.H

Because most professional software requires predictable memory layouts, we advise students to use the <stdint.h> header. Introduced in the C99 standard (1999), this header allows developers to specify exact widths regardless of the target architecture:

TypeDescription
int8_tSigned integer exactly 8 bits\text{exactly } 8 \text{ bits}exactly 8 bits
uint8_tUnsigned integer exactly 8 bits\text{exactly } 8 \text{ bits}exactly 8 bits
int16_tSigned integer exactly 16 bits\text{exactly } 16 \text{ bits}exactly 16 bits
uint16_tUnsigned integer exactly 16 bits\text{exactly } 16 \text{ bits}exactly 16 bits
int32_tSigned integer exactly 32 bits\text{exactly } 32 \text{ bits}exactly 32 bits
uint32_tUnsigned integer exactly 32 bits\text{exactly } 32 \text{ bits}exactly 32 bits

Defending a 1970s Design in a 2020s World

There is a common narrative in modern programming circles—often echoed on social media—that these platform-dependent types were a "design mistake."

twitter take on C integer type sizes

The argument is simple: int varies between 16 and 32 bits; long is 64 bits on Linux but 32 bits on 64-bit Windows. This inconsistency has fueled decades of portability bugs. But judging a 1970s decision by 2020s standards is anachronistic.

C was designed as a portable systems language meant to map efficiently to wildly different hardware. Its "portability" wasn't the Java-style "write once, run anywhere," but rather "write once, compile efficiently anywhere."

The Chaotic Hardware Landscape of the 60s and 70s

Today, we assume a world of 8-bit bytes, byte-addressable memory, and two's-complement arithmetic. In the early days, none of this was standard.

Historical Machine Word Sizes

MachineWord SizeNotable Characteristics
DEC PDP-812 bitsExtremely popular minicomputer
DEC PDP-718 bitsThe birthplace of UNIX (Assembly)
DEC PDP-1116 bitsByte-addressed; the environment where C matured
DEC PDP-1036 bitsCharacters often packed in 7 or 9-bit groups
Honeywell 600036 bits9-bit characters; an early C target
UNIVAC 110036 bitsOnes'-complement arithmetic; still has C compilers
IBM 709036 bitsUsed 6-bit character codes
SDS 940 / ICL 190024 bitsICL utilized 6-bit characters
Burroughs B500048 bitsTagged, stack-oriented architecture
CDC 660060 bits6-bit characters; no byte addressing
Cray-164 bitsWord-addressed; short, int, and long could all be 64-bit
DG Nova16 bitsWord-addressed; distinct pointer representations
Intel 808616 bitsSegmented memory (near/far pointers)

PDP-8 minicomputer PDP-11 minicomputer Data General Nova

The Complexity of Early Data

  • Characters: Ranged from 6-bit sets and 7-bit ASCII to 9-bit bytes and IBM's EBCDIC.
  • Negative Numbers: Represented via two's complement, ones' complement, or sign-magnitude.
  • Addressing: Some machines only addressed whole words. In such cases, a character pointer was calculated as: Effective Address=Word Address+Offset\text{Effective Address} = \text{Word Address} + \text{Offset}Effective Address=Word Address+Offset

The Lineage of C

C's philosophy is a direct evolution of its predecessors.

BCPL and B were typeless. A value was simply a bit pattern; whether it was treated as an address or an integer depended entirely on the operator used. This was incredibly efficient for word-addressed machines. When C emerged on the byte-addressed PDP-11, it needed to balance this efficiency with the emerging need for types.

Summary Checklist for C Portability

  • Avoid assuming int is 32 bits.
  • Use sizeof to determine memory footprints.
  • Use <stdint.h> for fixed-width requirements.
  • Respect the target architecture's word size.

playstation programming