Dennis Ritchie and the C Language
Abstract
Dennis Ritchie (1941–2011) spent his entire career at Bell Labs. Between 1969 and 1973 he co-created Unix with Ken Thompson and turned Thompson’s typeless B into C, a language close enough to the hardware to write an operating system kernel and abstract enough to move that kernel to other machines. With Brian Kernighan he wrote The C Programming Language (1978), the book that served as the language’s definition for more than a decade. C became the implementation language of Unix, Linux, Windows NT, the major databases and most language runtimes, and the syntactic ancestor of C++, Java, C#, and Go. Ritchie himself stayed in the same Murray Hill office from AT&T through Lucent to Alcatel-Lucent, ran the research department that produced Plan 9 and Inferno, and was found dead at home in October 2011, a week after Steve Jobs, to a fraction of the attention.
Family and Harvard
Dennis MacAlistair Ritchie was born on September 9, 1941, in Bronxville, New York, and grew up in Summit, New Jersey, a commuter town a few miles from the Bell Labs site at Murray Hill. Bell Labs was the family firm. His father, Alistair E. Ritchie, spent his career there as a switching engineer and co-authored, with William Keister and Seth Washburn, The Design of Switching Circuits (1951), which his son later described as “an influential book on switching theory and logic design just before the transistor era.” The son carried the connection in his middle name.
Ritchie went to Harvard, where he took a bachelor’s degree in physics and applied mathematics in 1963, then stayed for graduate work in applied mathematics. His own summary of the experience, written decades later for his Bell Labs home page:
“My undergraduate experience convinced me that I was not smart enough to be a physicist, and that computers were quite neat. My graduate school experience convinced me that I was not smart enough to be an expert in the theory of algorithms and also that I liked procedural languages better than functional ones.”
The self-deprecation undersold the work. Under his advisor Patrick Fischer, Ritchie studied subrecursive hierarchies of functions, and with his fellow student Albert Meyer he published “The Complexity of Loop Programs” at the 1967 ACM national conference. The paper introduced loop programs: programs built from nothing more than setting a variable to zero, adding one, copying a value, and repeating a block a fixed number of times. Restricting the nesting depth of those loops gave a clean hierarchy of computable functions; Meyer called the idea “so beautiful and so important.” Meyer later remembered Ritchie as “a very sweet, easy going, unpretentious guy” who was “already doing other things” by the time the collaboration ended.
Ritchie wrote up the work as a dissertation, “Program Structure and Computational Complexity,” in 1968, and never received the doctorate for it. According to Meyer, Harvard required a bound copy for its library, binding cost money, and Ritchie’s position was that if the library wanted a bound copy, the library could pay for it. The degree lapsed. For decades the dissertation was effectively lost; his sister Lynn went looking for it after his death, a copy turned up via his former advisor’s widow, and the Computer History Museum told the story in 2020. Official biographies, including the curriculum vitae issued for his 2011 Japan Prize, nonetheless list a 1968 Harvard Ph.D.
Bell Labs and Multics
Ritchie joined the Bell Labs Computing Sciences Research Center in 1967, while the thesis was still unfinished. The center was then one of the three partners, with MIT and General Electric, in Multics, the ambitious time-sharing system for the GE-645. Ritchie’s first jobs were compilers: he helped build the BCPL compiler on the GE-645 and on the GE-635 under GE’s GECOS operating system, and he wrote the compiler for ALTRAN, a Bell Labs language for symbolic algebra.
In 1969 Bell Labs withdrew from Multics, which was late and expensive and still could not serve many users. For the small group that had been using it (Thompson, Ritchie, Doug McIlroy, Joe Ossanna), the withdrawal took away a working environment that nothing else in the building could replace. Ritchie’s later account of what they wanted to rescue is the clearest statement of the Unix group’s motives:
“What we wanted to preserve was not just a good environment in which to do programming, but a system around which a fellowship could form. We knew from experience that the essence of communal computing, as supplied by remote-access, time-shared machines, is not just to type programs into a terminal instead of a keypunch, but to encourage close communication.”
Unix
Through 1969 the group proposed one new machine after another to management and was turned down each time. Meanwhile Thompson, Ritchie, and Rudd Canaday sketched a file system on blackboards and scribbled notes. “Most of the design was Thompson’s,” Ritchie wrote, “but I believe I contributed the idea of device files”: the convention that a terminal, a disk, or a tape drive appears in the file system as a file and is read and written like one. It became one of the defining traits of Unix.
Thompson had also written a game, Space Travel, that cost about $75 of CPU time per session on the GE mainframe. He found a little-used DEC PDP-7 with a good display, and he and Ritchie rewrote the game for it, writing their own floating-point package and character graphics because they “disdained all existing software.” That PDP-7 became the machine on which Thompson wrote the first Unix in the summer of 1969, with Ritchie as his closest collaborator. The full story is told in The Unix Story and Ken Thompson and Unix.
The project got its first real hardware through a change of pitch. In early 1970 the group asked for a DEC PDP-11 for about $65,000, an order of magnitude less than earlier requests, and promised a text-processing system rather than an unspecified operating system. Ossanna drove the proposal, and the order went out in May. The machine was among the first PDP-11s DEC delivered, and its disk arrived three months after the processor. By the second half of 1971 three typists from the Bell Labs patent department were preparing patent applications on the machine, which had no memory protection and a single half-megabyte disk; the patent department adopted Unix, and the group earned enough credit with management to keep going. The first edition of the Unix Programmer’s Manual, by Thompson and Ritchie, is dated November 1971.
In 1973 Ritchie and Thompson presented Unix at the ACM Symposium on Operating Systems Principles at IBM’s Yorktown Heights research center. The written version, “The UNIX Time-Sharing System,” appeared in Communications of the ACM in July 1974 and won the ACM award for the outstanding paper of that year in systems and languages. For most readers outside Bell Labs it was their introduction to Unix.
From B to C
The language Ritchie is known for grew out of the same constraints. BCPL, designed by Martin Richards at Cambridge in 1967, was a compact systems language with a single data type, the machine word. Ritchie knew it from the Multics compiler work. On the PDP-7, Thompson stripped BCPL down further into B, which Ritchie later called “BCPL squeezed into 8K bytes of memory.” B was typeless too: integers, characters, and pointers were all just words.
The PDP-11 broke that model. It addressed memory in 8-bit bytes, had 16-bit integers, and was soon to get floating-point hardware. A language that could not tell a byte from a word had to fake character handling with packing and unpacking routines, and B on the PDP-11 ran as interpreted threaded code. Ritchie’s first PDP-11 program in B was an assembler; the first serious test, before the machine had an operating system, was the desk calculator dc.
In 1971 Ritchie began extending B with a character type and rewrote its compiler to generate PDP-11 machine instructions. He called the result NB, “new B,” and it existed so briefly that no full description of it survives. Over 1971 and 1972 he added the type system that defines C: int and char, arrays and pointers composed according to rules borrowed from Algol 68, and a declaration syntax in which a declaration mirrors the expression that uses the variable (int *p declares that *p is an int). The new language, Ritchie wrote, “deserved a new name; NB seemed insufficiently distinctive. I decided to follow the single-letter style and called it C, leaving open the question whether the name represented a progression through the alphabet or through the letters in BCPL.”
Changes kept coming after the name. At the suggestion of Alan Snyder, Ritchie split the logical operators && and || from the bitwise & and |, which in B had done both jobs depending on context. Around 1972 and 1973 he added the preprocessor, again partly at Snyder’s urging; the first version handled only #include and simple #define substitutions, and Mike Lesk and John Reiser later added macros with arguments and conditional compilation. For years the preprocessor ran only if the source file began with a special marker, which is why its syntax never fully meshed with the rest of the language.
The decisive addition was structures. In 1972 Thompson tried to rewrite the Unix kernel in the early, structure-less C and gave up. Once Ritchie had added struct, the second attempt worked: by early 1973 the essentials of C were in place, and in the summer of 1973 Thompson and Ritchie rewrote the PDP-11 kernel in C. Writing an operating system kernel in a high-level language was not new (Multics was written in PL/I, and Burroughs had written its MCP in an Algol dialect), but no one had done it in a language this small, on a minicomputer, with performance close to hand-written assembly. Lesk wrote a “portable I/O package” for the new language, which was reworked into the standard I/O library, stdio, still found in every C installation.
What “Portable” Meant in 1973
The 1973 rewrite did not make Unix portable by itself. The kernel still assumed a PDP-11, and C still carried habits of its typeless ancestors (pointers and integers were used interchangeably in much of the early code). What the rewrite did was move the machine-dependent parts into a small, identifiable corner of the system. Porting became a matter of rewriting that corner and retargeting the compiler, which turned out to be weeks of work, not a rewrite in a new assembly language.
Portability
The proof came in 1977 and 1978. Ritchie, Steve Johnson, and Thompson moved Unix to the Interdata 8/32, a 32-bit minicomputer that resembled the PDP-11 in nothing that mattered. Johnson built pcc, the Portable C Compiler, designed to be retargeted to new machines, and lint, which flagged legal but suspicious C. Most of the language changes of the period (unsigned, long, union, enumerations, stricter rules for pointer conversion) came out of this work. Ritchie and Johnson described it in “Portability of C Programs and the UNIX System” in the Bell System Technical Journal in 1978. Their conclusion was that “the operating system interface caused far more trouble for portability than the actual hardware or language differences themselves.”
They were not alone. Richard Miller at the University of Wollongong in Australia was independently porting Unix to the Interdata 7/32, a near relative of the same machine, and neither group knew of the other when they started. Shortly afterward Tom London and John Reiser at Bell Labs used the Interdata version as the starting point for a port to DEC’s new VAX-11/780, which was distributed as 32V and became the base of the VAX versions of BSD. The Seventh Edition of Research Unix (1979), which included the portability changes, was the common ancestor of both AT&T’s commercial System V and the Berkeley distributions.
The C Programming Language
From 1973 to 1978 C was documented by Ritchie’s C Reference Manual, distributed with Unix, and by Kernighan’s tutorial. In 1978 Ritchie and Brian Kernighan published The C Programming Language with Prentice Hall: 228 pages, with a “hello, world” program on its first pages and short, complete examples throughout. Ritchie was precise about who did what: “Kernighan wrote almost all the expository material, while I was responsible for the appendix containing the reference manual and the chapter on interfacing with the Unix system.” The tutorial grew into the body of the book; the reference manual became Appendix A, and its structure and much of its wording survived into the ANSI standard.
Programmers called the book K&R, and for more than ten years it was the closest thing C had to a specification; a compiler was correct if it did what K&R said. By the early 1980s that was no longer enough. At Doug McIlroy’s urging, the American National Standards Institute set up the X3J11 committee in the summer of 1983. Its report appeared at the end of 1989 as ANSI X3.159-1989, adopted internationally as ISO/IEC 9899:1990. Ritchie praised the committee for its caution: it codified existing practice and made one change he considered important, function prototypes that declare the types of a function’s parameters, an idea borrowed back from C++. The second edition of K&R (1988) followed the draft standard and is still in print.
Ritchie’s own verdict, from his 1993 history of the language, is short: “C is quirky, flawed, and an enormous success.”
C as Infrastructure
When AT&T licensed Unix to universities in the 1970s, the license came with source code, and the source code was C. A generation of computer science students learned operating systems by reading it, and carried the language into industry.
- The Unix tools (
grep,awk,sed,make) were written in C. - The BSD networking code, through which TCP/IP spread to the academic world (see The Connected World), was C.
- Microsoft wrote MS-DOS in 8086 assembly language, but wrote the Windows NT kernel (1993) in C, keeping assembly to a few performance-critical routines so the system could move between processor architectures.
- The Linux kernel, which Linus Torvalds began in 1991 as a Unix-compatible system for the PC, is written in C and has grown to tens of millions of lines.
- The reference interpreters of Python, Perl, PHP, and Ruby, and databases such as PostgreSQL, SQLite, and MySQL, are written in C or C++.
The pattern behind all of these is the one the Interdata port established: if a C compiler exists for a machine, the software can follow.
The Children of C
C++ (Bjarne Stroustrup, Bell Labs, 1979–1983) began as “C with Classes” in the same research center and added classes, inheritance, and templates while keeping C’s performance model. Chrome, Firefox, and the V8 JavaScript engine are written in it.
Objective-C (Brad Cox and Tom Love, early 1980s), adopted by NeXT and then Apple, layered Smalltalk-style messaging on top of C. It was the language of macOS and iOS development until Swift took over.
Java (James Gosling, Sun Microsystems, 1995) took C’s braces, operators, and declarations and added garbage collection and a virtual machine; looking familiar to C and C++ programmers was an explicit design goal. C# (Anders Hejlsberg, Microsoft, 2000) followed the same template.
Python (Guido van Rossum, 1991) looks nothing like C but is implemented in it; CPython is a C program, and NumPy, TensorFlow, and PyTorch do their heavy lifting in C and C++ behind a Python interface.
Go (Ken Thompson, Rob Pike, and Robert Griesemer at Google, 2009) was designed by two of Ritchie’s longtime colleagues as a systems language with C’s spareness plus garbage collection and built-in concurrency.
Rust (begun by Graydon Hoare, sponsored by Mozilla Research from 2009; 1.0 in 2015) attacks C’s most expensive property, manual memory management, with an ownership system that the compiler checks. It has been accepted into the Linux kernel alongside C for new drivers.
Why C Is Still Here
C remains the default language for operating system kernels, embedded systems, and any code where memory layout and predictable performance matter more than safety. Ada, D, and Nim each found niches without displacing it. Rust is the first replacement with serious institutional backing, and its adoption is measured in decades: the existing body of C code, the compilers and debuggers built around it, and the programmers trained in it all have to move together.
Streams, Plan 9 and Inferno
Ritchie’s last major technical contribution to Unix was Streams, a framework for stacking protocol and device-driver modules between a device and a process, built for the Eighth Edition of Research Unix and described in “A Stream Input-Output System” (1984). AT&T ported it to System V Release 3, where it carried the networking code, and Release 4 rebuilt the terminal interface on it. Under the name STREAMS it also reached classic Mac OS (through Open Transport) and Windows NT.
From 1990 Ritchie headed a small research department in the Computing Sciences Research Center. His group built Plan 9 from Bell Labs, a distributed successor to Unix led by Pike, Thompson, Dave Presotto, and Phil Winterbottom (first released to universities in 1992, open-sourced in 2000), and Inferno, a portable network operating system with its own language, Limbo, announced in 1996 as an answer to Sun’s Java. Ritchie was candid about his share: on Plan 9 he “contributed only a few bits and pieces to it, but did, in effect, sign some paychecks to keep it going”; on Inferno it was “more a matter of signing paychecks than doing the work.” In 1996 AT&T spun off Bell Labs into Lucent Technologies, and in 2006 Lucent merged with Alcatel. Ritchie noted that through all of it he stayed “in the same office,” Room 2C-517 at Murray Hill. He retired in 2007.
The M-209 Episode
One of Ritchie’s side projects involved the National Security Agency. His colleague Robert H. Morris, co-author with Thompson of the Unix password scheme and author of the early crypt programs, owned a Hagelin M-209, the mechanical field cipher machine used by the US Army in the Second World War and after. Around 1975 Morris obtained a manuscript by James Reeds, then a Harvard student, describing a statistical ciphertext-only attack on the machine. Ritchie wrote a program implementing it, with Morris contributing the combinatorial second stage, and wrote most of a paper describing the method. The program produced readable decryptions of about half of all English messages longer than 2,000 characters and most of those over 2,500, with no guessed plaintext.
The authors submitted the paper to Cryptologia and, by agreement, also sent it to the NSA, asking whether the agency would rather they not publish; the internal version is dated July 1978. The answer came as a lunch visit from a man Morris called “a retired gentleman from Virginia,” who told them there was no legal bar to publication but that the method applied to commercial cipher machines some foreign governments still used, and suggested discretion. He also offered consulting contracts. The paper was never published. Ritchie told the story on his home page decades later; Morris went on to become chief scientist at the NSA’s National Computer Security Center.
The Man
People who worked with Ritchie describe the same person: quiet, precise, generous, and very funny in a dry way. His home page was a small museum of Unix history (scanned manuals, early compiler source, a 1981 Unix advertisement) annotated in his own voice. A page titled “My other lives” collected the web’s other Dennis Ritchies and claimed their careers as his own: a truck-driving safety director, a Nashville recording engineer, a recreation director in Carlstadt, New Jersey, and the poultry division chairman of the Arkansas Farm Bureau. In his account of receiving the National Medal of Technology at the White House, he recorded that the first draft of the Commerce Department press release gave his name as “Daniel” (fixed before it went out), and that the event required him and Thompson to “behave and wear clothing outside our usual custom.”
He had no interest in defending Unix against all criticism, and no patience with critics who only complained. When Simson Garfinkel, Daniel Weise, and Steven Strassmann published The UNIX-Haters Handbook in 1994, Ritchie contributed an “Anti-Foreword” that included the line: “You claim to seek progress, but you succeed mainly in whining.” On the subject of his shared honors he wrote: “Ken’s virtual coat-tails are long.”
Honors
Almost every award Ritchie received he shared with Thompson. The ACM gave them the Turing Award for 1983, “for their development of generic operating systems theory and specifically for the implementation of the UNIX operating system.” Thompson used his lecture for “Reflections on Trusting Trust,” the description of a self-replicating compiler backdoor; Ritchie’s, “Reflections on Software Research” (Communications of the ACM, August 1984), was about the management that made Unix possible, a research center that hired good people and let them pick their problems. The list continued with the IEEE Emanuel R. Piore Award (1982), Bell Labs Fellow and the ACM Software System Award (1983), election to the National Academy of Engineering (1988), the NEC C&C Prize (1989), the IEEE Richard W. Hamming Medal (1990), the 1998 National Medal of Technology, presented by President Clinton in April 1999, and the Japan Prize for information and communications in 2011, worth about $600,000, which was presented to Ritchie and Thompson at Murray Hill in May 2011.
Death
Ritchie lived alone in Berkeley Heights, New Jersey, and had been in frail health after treatment for prostate cancer and heart disease. He was found dead at home on October 12, 2011, at the age of 70. Steve Jobs had died on October 5, and the contrast in coverage became a story of its own (see The Death Nobody Noticed). Kernighan, quoted in the obituaries, said that the tools Ritchie built and their direct descendants “run pretty much everything today.” Tim O’Reilly declared October 30, 2011, “Dennis Ritchie Day.” His siblings Lynn, John, and Bill posted a note on his Bell Labs page thanking the people who had written tributes and describing him as “an unfailingly kind, sweet, unassuming, and generous brother” and “of course a complete geek.”
Dead End: BCPL and B
BCPL and B were not abandoned for being bad ideas; they were outgrown by their own descendant.
BCPL showed that a typeless language could be compiled efficiently on very different machines, and it was used for compilers and operating systems well beyond Cambridge. But a single data type works only on machines with a single natural word size. Once byte-addressed machines with several data sizes became the norm in the early 1970s, a typeless language generated slow or incorrect code for them.
B inherited that limit. It ran as interpreted threaded code on the PDP-7 and then the PDP-11, and Ritchie wrote a cross-compiler that produced native code for the 36-bit GE-635; none of these versions could reason about data sizes, because the language had no types to reason with.
The PDP-11’s byte addressing made the problem impossible to ignore. Ritchie’s types were not a software engineering ideal imposed on systems programmers; they were the minimum needed to describe the memory of the machine on the desk. B lingered at the University of Waterloo, where Steve Johnson had brought it on a 1972 sabbatical and where it spawned the successors Eh and Zed, and faded elsewhere as C spread. BCPL survived longer in Britain and in teaching. Neither had a reason to exist once C ran everywhere they did.
The Cost of Raw Memory
C trusts the programmer with raw addresses, and the trust has a price. Buffer overflows, use-after-free errors, and null pointer dereferences all follow from that design. The 1988 Morris worm, written by the son of Ritchie’s colleague Robert H. Morris, broke into VAX machines partly by sending 536 bytes to the fingerd daemon, which read its input with the C library routine gets() into a 512-byte buffer that the routine had no way to bound. Much of the history of computer security since then has been the history of C programs writing past the end of something. Rust and the memory-safety push by governments and vendors in the 2020s are attempts to keep C’s control over memory while removing that class of bug.
📚 Sources
- Ritchie, Dennis M.: “The Development of the C Language” — HOPL II / ACM SIGPLAN Notices, Vol. 28, No. 3 (1993) (author’s online version: Nokia Bell Labs)
- Ritchie, Dennis M.: “The Evolution of the Unix Time-sharing System” (1979/1984), author’s online version — Multics withdrawal, file system, PDP-11 proposal, patent department
- Ritchie, Dennis M.: Home page and first-person biography, Bell Labs (archived by Nokia Bell Labs) — birth, Harvard, Multics compilers, Interdata port, Streams, Plan 9/Inferno, awards; main page with siblings’ note and corporate history
- Ritchie, Dennis M. & Johnson, Stephen C.: “Portability of C Programs and the UNIX System” — Bell System Technical Journal 57(6) (1978), with notes on Miller’s Wollongong port and 32V
- Ritchie, Dennis M. & Thompson, Ken: “The UNIX Time-Sharing System” — Communications of the ACM 17(7) (1974)
- Ritchie, Dennis M.: “A Stream Input-Output System” — AT&T Bell Laboratories Technical Journal 63(8) (1984)
- Wikipedia: STREAMS — Eighth Edition origin, System V Release 3/4 adoption, later implementations
- Ritchie, Dennis M.: “Reflections on Software Research” — Turing Award lecture, Communications of the ACM 27(8) (1984)
- Ritchie, Dennis M.: “Dabbling in the Cryptographic World: A Story” — the M-209 paper and the NSA visit
- Ritchie, Dennis M.: “Letter from Washington: The National Medal of Technology Experience” (1999)
- Ritchie, Dennis M.: “My other lives”
- Computer History Museum: “Discovering Dennis Ritchie’s Lost Dissertation” (2020) — loop programs, Meyer, the unpaid binding fee
- Japan Prize Foundation: Curriculum Vitae of Dennis M. Ritchie, 2011 Japan Prize Laureate (January 2011) — degrees, Bell Labs positions, department head from 1990, retirement 2007, honors
- The Register: “Unix dynamic duo awarded Japan Prize” (January 2011)
- Philadelphia Inquirer: “Dennis M. Ritchie, software pioneer, 70” (October 15, 2011) — circumstances of death, Kernighan quote
- O’Reilly: “Dennis Ritchie Day” (October 2011)
- Garfinkel, Simson; Weise, Daniel & Strassmann, Steven (eds.): The UNIX-Haters Handbook (1994), with Ritchie’s “Anti-Foreword”
- Computer History Museum: “Microsoft MS-DOS early source code” — MS-DOS 1.1 and 2.0 written in assembly
- Wikipedia: Windows NT — implementation in C and C++, minimal assembly
- Wikipedia: Plan 9 from Bell Labs — team, release dates, Inferno and Limbo
- Seeley, Donn: “A Tour of the Worm” (1989) — the
fingerdgets()overflow - Kernighan, Brian W. & Ritchie, Dennis M.: The C Programming Language, 2nd ed. (1988), Prentice Hall
- Ritchie, Dennis M.: “C Reference Manual” — Bell Laboratories (1975)
- Keister, William; Ritchie, Alistair E. & Washburn, Seth H.: The Design of Switching Circuits (1951), Van Nostrand
- Kernighan, Brian W.: UNIX: A History and a Memoir (2019), Kindle Direct Publishing
- Richards, Martin: “BCPL: A tool for compiler writing and systems programming” — AFIPS Spring Joint Computer Conference (1969)
- Salus, Peter H.: A Quarter Century of UNIX (1994), Addison-Wesley
- Stroustrup, Bjarne: The Design and Evolution of C++ (1994), Addison-Wesley
- Matsakis, Nicholas D. & Klock, Felix S.: “The Rust Language” — ACM SIGAda Ada Letters, Vol. 34, No. 3 (2014)
- Image: Dennis Ritchie 2011.jpg by Denise Panyik-Dale (CC BY 2.0), via Wikimedia Commons