The Development of the C Language
📜 Abstract
The C programming language was devised in the early 1970s as a system implementation language for the nascent Unix operating system. Derived from the typeless language BCPL, it evolved a type structure; created on a tiny machine as a tool to improve a meager programming environment, it has become one of the dominant languages of today. This paper studies its evolution.
✨ Summary
Summary
Dennis M. Ritchie presents a historical account of how C emerged alongside the early Unix operating system between 1969 and 1973. The language developed from Martin Richards’s BCPL through Ken Thompson’s B, with each stage shaped by severe hardware and memory constraints, the need for compact compilers, and the practical requirements of system programming.
The transition from B to C was driven particularly by the PDP-11’s byte-addressed architecture, the need for efficient character handling, anticipated floating-point support, and the performance limitations of B’s threaded-code implementation. Ritchie explains that the introduction of int, char, pointers, arrays, and later structures produced a typed language capable of generating code sufficiently small and fast to compete with assembly language. A central design decision was to avoid storing array-base pointers inside objects and instead convert array expressions to pointers when needed. This decision enabled structures containing arrays while preserving substantial compatibility with earlier B programs.
The paper also traces the development of C’s declaration syntax, whose form mirrors the syntax used to access declared objects in expressions. It attributes important conceptual influences to Algol 68 and practical influences to BCPL, PL/I, Unix, and the characteristics of the PDP-7 and PDP-11. The preprocessor, including file inclusion, macro substitution, parameterized macros, and conditional compilation, became an important part of the C programming environment even though it was initially treated as an adjunct rather than an integrated language feature.
Portability became a major concern during the late 1970s, as Unix and C were moved to systems such as the Interdata 8/32 and DEC VAX. These efforts encouraged improvements to C’s type rules, pointer handling, casts, unsigned types, compiler retargetability, and diagnostic tools such as lint. The 1978 publication of The C Programming Language provided the first broadly available description of the language, while ANSI X3J11 standardization, completed in 1989 and adopted by ISO in 1990, codified subsequent practice without fundamentally changing C’s character. (nokia.com)
Ritchie’s critique emphasizes that C’s most distinctive features—its relationship between arrays and pointers and its declaration syntax—are also major sources of difficulty. The language provides limited support for modularization, automatic memory management, and strong type checking, and its pointer-oriented array model complicates optimization and some future extensions. Nevertheless, he attributes C’s success to its small size, straightforward compilation model, close correspondence with machine operations, practical connection to Unix and systems software, and ability to express efficient programs across many architectures.
The paper’s continuing influence is primarily historical and documentary rather than algorithmic. It is widely used as a reference for the origins of C, B, BCPL, Unix-related portability work, and C’s design tradeoffs; Semantic Scholar lists approximately 179 citing works. Later technical publications, including work on garbage collection and low-level programming and research software in computational chemistry, cite it as historical background when discussing C’s role in systems and scientific computing. (semanticscholar.org)