Computing history · Part 2 of 8

The C language and why it's still everywhere

Feb 17, 20268 min read#computing-history#history#c#programming

The C language and why it's still everywhere

Field note. The JVM your Minecraft server runs is written in C. The Wings daemon is Go (descended from C). UNIX is C. The language matters because everything below your game is written in it.

In 1972, Dennis Ritchie at Bell Labs designed a programming language he called C. He needed it to rewrite UNIX in something more portable than assembly. C was meant to be a small, practical, systems language for the specific machines of its era.

Fifty-four years later, C is still one of the most-used programming languages in the world. Every operating system kernel. Most embedded systems. Most database engines. Most language runtimes (including Python's CPython, Ruby's MRI, Node.js's V8). The web servers, the network stacks, the boot loaders.

This article explains why a language designed for 1970s minicomputers is still everywhere.

What came before C

Before C, systems programming was done in:

Assembly language. Specific to each CPU architecture. Fast but unportable. Programs had to be largely rewritten for each new machine.

FORTRAN. Numerical computing. Not suited to systems programming (no good way to manipulate memory directly).

COBOL. Business applications. Wrong domain for OS work.

PL/I, ALGOL, others. Had nice features but were complex, slow to compile, and didn't fit Bell Labs' minicomputer constraints.

BCPL and B. Earlier languages that influenced C. Ken Thompson's B (named after BCPL) was used to write some early UNIX tools. B was simple but had only one type (the machine word).

Ritchie wanted something that:

  • Could express low-level operations.
  • Was typed (unlike B).
  • Could compile to small, fast code on a PDP-11.
  • Was portable across machines.

He started designing C in 1971-1972.

C's design

C ended up with a small set of features:

  • Static typing, but with extensive implicit conversions.
  • Pointers. Direct memory addresses as a language feature.
  • Structures. Composite types.
  • Arrays. Closely tied to pointers.
  • Standard control flow. if/else, for, while, switch.
  • Functions. With separate compilation.
  • Preprocessor. A simple macro system for textual substitution.
  • A small standard library. I/O, string operations, memory allocation.

What it didn't have:

  • Garbage collection.
  • Object orientation.
  • Built-in dynamic data structures.
  • Built-in concurrency.
  • Module system (just header files).
  • Bounds checking.

This was deliberate. C was meant to be a "portable assembly," giving you direct hardware access in a portable form.

K&R: the book that taught the world

In 1978, Brian Kernighan and Dennis Ritchie published "The C Programming Language." The book was concise (~200 pages), well-written, and influential.

K&R became the standard reference for C. A generation of programmers learned C from it. The book taught C; C taught its readers about systems thinking, pointers, memory management. Many of its examples are still used in courses today.

What made C succeed

Several factors compounded:

UNIX was C. UNIX's spread carried C with it. Every Unix workstation needed a C compiler. Every Unix programmer wrote C.

Portability. C compilers existed for nearly every architecture by the mid-1980s. The same C code could run on PDP-11, VAX, IBM 360, Mac 68000, 386 PCs, and so on. Few languages had this reach.

Performance. C compiled to fast code. Comparable to hand-written assembly for many problems. No runtime overhead.

Simplicity. C was small enough to learn fully. The whole language fit in the K&R book. Easy to teach.

Pragmatism. C wasn't pure or elegant by language-theory standards. It was practical. It worked.

Lack of strong competitors. PL/I, Algol, BCPL had all faded. Pascal was niche. Ada was complex and government-mandated. C had no real rival for systems programming through the 1980s.

By the early 1980s, C was the systems language of choice for new operating systems. By the late 1980s, it was the dominant programming language overall.

Standardization: ANSI C (1989)

By 1980, C had spread enough that compatibility was a problem. Different compilers had drifted. A program written for one compiler might not work on another.

ANSI (American National Standards Institute) chartered a committee to standardize C in 1983. The result, ANSI C (later called C89 or C90), was published in 1989. ISO adopted it in 1990.

ANSI C codified the language, added some features (function prototypes, void type), and clarified ambiguous behaviors.

Later standards:

  • C99 (1999): added bool, variable-length arrays, inline functions, some other modern features.
  • C11 (2011): better Unicode, multithreading, atomics.
  • C17 (2017): minor corrections to C11.
  • C23 (2023): more modern features, attributes, decimal floating-point.

C has evolved slowly. The 1989 standard is still mostly correct in 2026. The conservative evolution is part of why old C code still compiles on modern compilers.

C++ (a side branch)

In the early 1980s, Bjarne Stroustrup at Bell Labs began work on what would become C++. The idea: C with object orientation, classes, templates, and more sophisticated abstractions.

C++ standardized in 1998 (C++98), with major revisions in C++11, C++14, C++17, C++20, C++23. It's evolved much more rapidly than C.

C++ is widely used (browsers, games, financial systems) but has a different feel. Where C is small and simple, C++ is large and feature-rich. Whether to consider C++ "the next C" or "a separate language" is largely cultural. Many C codebases never moved to C++; many C++ codebases use C primitives extensively.

C in 2026

What does C still get used for?

Operating system kernels. Linux is C. Windows kernel has C and C++. BSDs are C. Most RTOS (real-time OS) for embedded systems are C.

Embedded systems. Microcontrollers (Arduino, ESP32, STM32) overwhelmingly use C. The constraints of tiny systems (small RAM, limited CPU) match C's lightweight runtime.

Language runtimes. CPython (Python's interpreter) is C. Ruby's MRI is C. Lua is C. Node.js's V8 is C++. PHP's Zend Engine is C. These are the engines under most "high-level" languages.

Databases. PostgreSQL, MySQL/MariaDB, SQLite, Redis: largely C.

Network infrastructure. nginx is C. OpenSSL is C. Most network protocol implementations are C.

Game engines and graphics. Some C, much C++. The performance constraints push toward C-style code.

Critical infrastructure. PCI banks' systems, industrial control systems, aerospace. Often C for verifiability and performance.

C remains where performance, portability, and low overhead matter most.

C's problems

C has well-known weaknesses:

Memory unsafety. Buffer overflows, use-after-free, null pointer dereferences. These are the basis of most security vulnerabilities historically.

Undefined behavior. The language standard leaves many behaviors undefined ("the compiler can do anything"). Modern compilers exploit this for optimization, leading to surprising bugs.

No bounds checking. Arrays don't know their size.

Manual memory management. Easy to mishandle, especially in complex programs.

Limited abstraction. Building large systems in C requires manual discipline. No built-in classes, modules, generics.

These weaknesses have driven the development of safer alternatives.

The C-replacement era

Several languages have aimed to be "the new C":

Rust (Mozilla, 2010+). Memory-safe systems language. Strong type system, ownership model that catches memory bugs at compile time. Increasingly adopted for new systems work.

Zig (2016+). Simpler than Rust, still memory-safer than C. Direct interop with C. Growing user base.

Go (Google, 2009). Higher-level than C, garbage-collected. Used for servers, CLI tools, infrastructure. Not really a C replacement (different niche).

C++. Already mentioned. Used for many performance-critical applications where C's weaknesses are felt.

Rust in particular has seen real adoption: parts of Linux, Firefox, Chromium, parts of Windows, Tor's relay code, Discord's backend. Microsoft has stated that 70 percent of their security vulnerabilities are memory-safety issues, and they're actively migrating to Rust where possible.

The trend is real but slow. C codebases are vast (tens of millions of lines in Linux alone). Rewriting all of them is unrealistic. New code can be written in Rust or Zig; old code stays in C.

Why C won't fully die

A few reasons C will be used indefinitely:

Existing code. Untold billions of lines of C exist. Maintaining and incrementally improving them is the rational choice.

Embedded systems. The hardware constraints favor C's minimalism. Rust runs on microcontrollers but isn't as easy to deploy as C.

Talent. Millions of programmers know C. New languages take generations to match this base.

Interop. C's ABI (binary calling conventions) is the cross-language lingua franca. Want Python to call your library? Expose a C interface. Want Rust to call your library? Expose a C interface.

Stability. C from 1989 still compiles in 2026. Few languages have this kind of backward compatibility.

C will probably be used for at least another 30-40 years. New systems will use newer languages. Existing systems will be maintained in C.

A look at "Hello, World!"

The first program almost every C student writes:

#include <stdio.h>

int main(void) {
    printf("Hello, World!\n");
    return 0;
}

This works on Linux, macOS, Windows, BSD, almost any system with a C compiler. Same code, same output. In 1978, K&R taught it this way. In 2026, students learn it the same way.

That stability is part of C's enduring appeal.

What learning C teaches you

Even if you don't write C professionally, learning some C is educational:

  • How memory works (pointers, allocation, deallocation).
  • How operating systems present resources (file descriptors, processes).
  • Why high-level languages are doing what they do (and what they're hiding from you).
  • How performance constraints shape language design.
  • The substrate that almost all software ultimately rests on.

Many programmers skip C and learn directly with higher-level languages. Most modern code is written in higher-level languages. But the foundation is still C.

Conclusion

C is a 1972 language that runs the world in 2026. It's not because nothing better has been invented. It's because C's tradeoffs (small, simple, fast, portable, close to hardware) match a permanent set of needs in computing.

New systems will use Rust, Zig, or whatever comes next. Existing systems (vast in number) will be maintained in C indefinitely. The dual track will continue for decades.

For anyone working in software infrastructure (operating systems, databases, networks, embedded), knowing C is still essential. For everyone else, knowing some C is a useful window into how computers actually work.

Dennis Ritchie's small, practical language became the most influential programming language ever created. The unassuming nature of the design is part of why it persisted.

Coming up

Next: the PC era. Apple, IBM, Microsoft, and the home computer revolution. How computing moved from professional and academic settings to almost every desk in the world.


Hosting your game server with AndroHost means we handle most of what's in this post for you automatically: tier sizing, SRV records, off-site backups, DDoS protection.

Browse plans·More posts·Discord