Previous | Table of Contents | Next |
By early 1973, the essentials of modern C were complete. The language and compiler were strong enough to permit us to rewrite the UNIX kernel for the PDP-11 in C during the summer of that year. (Thompson had made a brief attempt to produce a system coded in an early version of C before structures in 1972 but gave up the effort.) Also during this period, the compiler was retargeted to other nearby machines, particularly the Honeywell 635 and IBM 360/370; because the language could not live in isolation, the prototypes for the modern libraries were developed. In particular, Lesk (1973) wrote A Portable I/O Package, which was later reworked to become The C Standard I/O Routines. In 1978, Brian Kernighan and I published The C Programming Language (Kernighan & Ritchie, 1978). Although it did not describe some additions that soon became common, this book served as the language reference until a formal standard was adopted more than 10 years later. Although we worked closely together on this book, there was a clear division of labor: Kernighan wrote almost all the expository material, and I was responsible for the appendix containing the reference manual and the chapter on interfacing with the UNIX system.
During 19731980, the language grew a bit: The type structure gained unsigned, long, union, and enumeration types, and structures became nearly first-class objects (lacking only a notation for literals). Equally important developments appeared in its environment and the accompanying technology. Writing the UNIX kernel in C had given us enough confidence in the languages usefulness and efficiency that we began to recode the systems utilities and tools as well and then to move the most interesting among them to the other platforms. As described in Portability of C Programs and the UNIX System (Johnson & Ritchie, 1978), we discovered that the hardest problems in propagating UNIX tools lay not in the interaction of the C language with new hardware, but in adapting to the existing software of other operating systems. Thus Steve Johnson began to work on pcc, a C compiler intended to be easy to retarget to new machines (Johnson, 1978) while he, Thompson, and I began to move the UNIX system itself to the Interdata 8/32 computer.
The language changes during this period, especially around 1977, were largely focused on considerations of portability and type safety in an effort to cope with the problems we foresaw and observed in moving a considerable body of code to the new Interdata platform. C at that time still manifested strong signs of its typeless origins. Pointers, for example, were barely distinguished from integral memory indices in early language manuals or extant code; the similarity of the arithmetic properties of character pointers and unsigned integers made it hard to resist the temptation to identify them. The unsigned types were added to make unsigned arithmetic available without confusing it with pointer manipulation. Similarly, the early language condoned assignments between integers and pointers, but this practice began to be discouraged; a notation for type conversions (called casts from the example of Algol 68) was invented to specify type conversions more explicitly. Beguiled by the example of PL/I, early C did not tie structure pointers firmly to the structures they pointed to and permitted programmers to write pointer>member almost without regard to the type of pointer; such an expression was taken uncritically as a reference to a region of memory designated by the pointer, whereas the member name specified only an offset and a type.
Although the first edition of K&R described most of the rules that brought Cs type structure to its present form, many programs written in the older, more relaxed style persisted and so did compilers that tolerated it. To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint (Johnson, 1979), which scanned a set of files and remarked on dubious constructions.
The success of our portability experiment on the Interdata 8/32 soon led to another by Tom London and John Reiser on the DEC VAX 11/780. This machine became much more popular than the Interdata, and UNIX and the C language began to spread rapidly, both within AT&T and outside. Although by the middle 1970s UNIX was in use by a variety of projects within the Bell System as well as a small group of researchoriented industrial, academic, and government organizations outside our company, its real growth began only after portability had been achieved. Of particular note were the System III and System V versions of the system from the emerging Computer Systems division of AT&T, based on work by the companys development and research groups and the BSD series of releases by the University of California at Berkeley that derived from research organizations in Bell Laboratories.
During the 1980s, the use of the C language spread widely, and compilers became available on nearly every machine architecture and operating system; in particular, it became popular as a programming tool for personal computers, both for manufacturers of commercial software for these machines and for end users interested in programming. At the start of the decade, nearly every compiler was based on Johnsons pcc; by 1985, there were many independently produced compiler products.
Previous | Table of Contents | Next |