THE 1970S

C

At Bell Labs in the early 1970s, the mood was far from optimistic. The company had just walked away from Multics, that monumental project undertaken with MIT and General Electric that had consumed considerable budgets without delivering on its promises. Disappointed, Ken Thompson decided to take matters into his own hands to create his own computing environment, according to his personal vision.

He salvaged an old DEC PDP-7, a machine already outdated with its meager 8 KB of memory. On it, he built the first versions of UNIX, initially in assembly language. But programming directly in assembly was a daily nightmare. Thompson had tested Fortran, without success. He created B, a stripped-down version of BCPL that fit within the PDP-7’s memory constraints.

Dennis Ritchie joined the team and found that B had its limitations. Between 1969 and 1973, he undertook to evolve it into something more ambitious. 1972 was the decisive year. The move to the PDP-11 revealed B’s weaknesses: its character handling was problematic, and its pointers generated absurd conversions between word indices and addresses. B completely ignored floating-point numbers, even though the PDP-11 would soon be able to handle them.

Ritchie first introduced types with “New B”, adding int and char with their arrays and pointers. But it was with C that the idea truly took shape. The type system became sophisticated, allowing the composition of complex structures from basic types. Ritchie had a brilliant insight for declaration syntax: make it mirror usage. If you write int *p, it’s because *p gives you an int.

Array handling sparked debates. In C, an array name automatically converts to a pointer to its first element in expressions. This approach elegantly solved the string problem while preserving existing B code. The preprocessor arrived in 1972-1973, modest at first with just file inclusion and a few macros.

By 1973, C was mature. Ritchie and Thompson tackled a complete rewrite of the UNIX kernel. It was a bold gamble: no one had yet proven that a high-level language could produce code fast enough for an operating system. The gamble paid off. Between 1973 and 1980, C continued to grow: unsigned and long types, union, enumerations, structures becoming first-class citizens.

Brian Kernighan and Dennis Ritchie published The C Programming Language in 1978. This small white book, which everyone called “K&R”, became the language’s bible. Its remarkable clarity contributed greatly to popularizing C. But the language lacked an official standard, and each compiler brought its own small variations.

Standardization became necessary in the early 1980s. C was overflowing from UNIX and colonizing other systems. The ANSI X3J11 committee formed in 1983 at the initiative of M. D. McIlroy. By the end of 1989, the ANSI C standard was ready, adopted as international standard ISO/IEC 9899-1990. The committee remained cautious, introducing only one major change: integrating argument types into function signatures. This idea, borrowed from C++, strengthened type checking without breaking existing code.

C’s expansion was meteoric. In the 1980s, compilers appeared on virtually every architecture and system. Commercial software developers for microcomputers adopted it massively. This success stemmed from the language’s balance: simple enough to master, close enough to the machine to produce efficient code, abstract enough for portability.

C spawned a prolific lineage. Bjarne Stroustrup created C++, and others gave birth to Objective C and Concurrent C. Subsequently, the modern languages that borrowed its syntax and concepts are countless. Pointers, array handling, and type declaration syntax remain lasting contributions, even if they spark debate.

The language has its flaws. Modularizing large systems remains problematic with its two-level naming structure. Manual dynamic memory management regularly traps programmers. These weaknesses have not, however, prevented the development of complete operating systems in C.

The history of C shows how a tool born from immediate practical necessities becomes, through judicious design choices, a standard that spans eras. Its longevity in a constantly shifting technological landscape testifies to the soundness of its creators’ insights. More than fifty years after its birth, C still ranks among the most widely used languages in systems and embedded programming. Go, of which Ken Thompson is co-creator, is trying to catch up with it.