A Brief History of the Development of the C Language

Author: Li Yanfeng, Tencent IEG Operations Development Engineer

I have always wanted to write an article about the C language, including its history, founders, and related events. However, I have delayed writing it mainly because I feel that this language is too great and brilliant. As an ordinary developer who has only used C language, I feel completely unqualified to write about it. However, after reading an article titled “The History of the C Language” by Dennis Ritchie, I have strengthened my determination to write this article. This is not a glorification, but merely an appreciation from an objective perspective.

1. The History of the C Language

The emergence of any new thing is not a coincidence, but an inevitable result driven by the times.

1.1 How Great is the C Language

If you ask me: How great is the C language? I might think for a moment and say: I don’t know how great it is, but I know it is very great.

A Brief History of the Development of the C Language

Here, I want to say something that may be a bit one-sided: Nowadays, wherever there is electricity in the world, there may be its (C language) or its descendants’ shadow.

No language lower than C can completely abstract a computer system; any language higher than C can be implemented in C.

1.2 The Father of the C Language

A Brief History of the Development of the C Language

Ritchie’s personal homepage at Bell Labs: https://www.bell-labs.com/usr/dmr/www/index.html

Dennis MacAlistair Ritchie (September 9, 1941 – October 12, 2011) was an American computer scientist. He is often referred to as “dmr” in hacker circles. He is the creator of the C language and a key developer of the Unix operating system, having a profound impact on the field of computing, and was a co-recipient of the Turing Award in 1983 along with Ken Thompson.

A Brief History of the Development of the C Language
Dennis Ritchie’s Timeline

Professor Martin from the MIT Computer Science Department commented: “If Steve Jobs is the king of visual products, then Ritchie is the monarch of the invisible kingdom. Jobs’ contribution lies in his deep understanding of user needs and desires, leading to the creation of technology products that contemporary people cannot forget. However, it was Mr. Ritchie who provided the core components for these products, which people cannot see but use every day.”

Kernighan remarked: Newton said he stood on the shoulders of giants; today, we all stand on Ritchie’s shoulders.

1.3 The Ancestors of the C Language

For the sake of brevity, I (Dennis M. Ritchie) will omit a full description of C itself, its parent B [Johnson 73], and its grandparent BCPL [Richards 79], and instead focus on the characteristic elements of each language and how they evolved.

This paper is about the development of the C programming language, the influences on it, and the conditions under which it was created. For the sake of brevity, I omit full descriptions of C itself, its parent B [Johnson 73], and its grandparent BCPL [Richards 79], and instead concentrate on characteristic elements of each language and how they evolved.

https://www.bell-labs.com/usr/dmr/www/chist.html

This text is from an article written by the father of the C language, Dennis M. Ritchie, about “The History of the C Language”, which clearly states that the C language originated from the B and BCPL languages. The C language can be seen as standing on the shoulders of giants, following the trend of the times.

1.3.1 The Father of BCPL Language

A Brief History of the Development of the C Language

Martin Richards

Martin Richards’s BCPL Reference Manual, 1967: https://web.archive.org/web/20080622171914/http://cm.bell-labs.com/cm/cs/who/dmr/bcpl.html

Martin Richards (July 21, 1940 – ) is a British computer scientist and the inventor of the BCPL programming language, who developed the TRIPOS operating system.

In 1966, Martin Richards invented the BCPL programming language based on the CPL programming language at the University of Cambridge.

1.3.2 The Father of B Language
A Brief History of the Development of the C Language
Kenneth Lane Thompson

Kenneth Lane Thompson (February 4, 1943 – ) is an American computer scientist and engineer, often referred to as “Ken” in hacker culture. While working at Bell Labs, Thompson designed and implemented the Unix operating system. He created the B language (based on BCPL) — the predecessor of the C language, and was one of the creators and developers of the Plan 9 operating system. He was also a co-recipient of the Turing Award in 1983 along with Dennis Ritchie.

In 2006, Thompson joined Google and co-designed the Go language.

1.3.3 A Collection of Photos of Ken and Dennis

Continuously improving

Standing on the shoulders of giants

A Brief History of the Development of the C Language
Ken sitting, Dennis standing

Being with excellent people

Fearless of gains and losses, doing interesting things

A Brief History of the Development of the C Language
Left Ken, Right Dennis | Top Right: Unix Signboard

Teaching by example

Thanks to Dennis Ritchie for leaving the world a “C Language Bible”.

Unfortunately, I learned C language from Teacher Tan Haoqiang in college.

A Brief History of the Development of the C Language
Dennis with “The C Programming Language”

Mutual achievement

Ultimately fruitful

What you do will eventually be seen by the world

A Brief History of the Development of the C Language

1999 National Technology Award [Left: Ken | Second from Left: Dennis | Right: Clinton]

From these old photos, I vaguely see a few lines of small text, saying:

1. Be with excellent people

2. Mutual achievement

Imagine how important this is?

1.4 Timeline of the C Language

A Brief History of the Development of the C Language

Computer Languages History: https://www.levenez.com/lang/

From the timeline in the figure, the origin and time nodes of the C language can be clearly seen.

Sometimes it must be said that the times create heroes. Between 1969 and 1971, the famous operating system Unix was born from Ken Thompson’s hands. As a large-scale systemic software, it urgently needed the emergence of a reliable high-level language (the low-level language at that time referred to assembly, as previous operating systems were written in assembly). During this time, Dennis Ritchie was also busy, and after improving the B language, the typed C language was born (according to Ritchie himself, there was a time when this improved language was called NB, meaning: new B. However, from our perspective, it indeed seems quite impressive).

In 1971 I began to extend the B language by adding a character type and also rewrote its compiler to generate PDP-11 machine instructions instead of threaded code. Thus the transition from B to C was contemporaneous with the creation of a compiler capable of producing programs fast and small enough to compete with assembly language. I called the slightly-extended language NB, for `new B.’

1.5 Unix Timeline

A Brief History of the Development of the C Language

The birth of Unix is closely related to the widespread dissemination and use of the C language.

The timeline above only shows the first few Unix versions that were born in the same time period as the C language (of course, if interested, one can look up the history of Unix development, which will definitely surprise you. The most famous branches include: BSD, minix, Linux…).

Next, we will trace back to the timing of the emergence of the C language through some Unix kernel source code found online.

1.5.1 PDP-Unix

PDP-Unix system kernel code file

A Brief History of the Development of the C Language

PDP-7 Unix: https://minnie.tuhs.org/cgi-bin/utree.pl?file=PDP7-Unix

It can be seen that it is mostly written in assembly (file extension .s). Why use the word mostly? Because there are some commands in the system that are written in B language.

1.5.2 First Edition Unix

First Edition Unix system kernel code file

A Brief History of the Development of the C Language

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V1

It can be seen that it is still written in assembly (file extension .s).

1.5.3 Second Edition Unix

Second Edition Unix system kernel code file

A Brief History of the Development of the C Language

Second Edition Unix: The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

By this version, we can already see the shadow of the C language.

1.5.4 Unix and C Language

From the appearance of the C language in Unix V2, starting from Unix V3, a large amount of code written in C can be seen in the Unix kernel.

According to Ritchie, 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.

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.

At this point, it can be confirmed that most of the core of the C language and Unix has been perfected. What remains to be done is portability and standardization.

The subsequent story is well-known: later, Unix was used in academic and government organizations, and it was precisely due to the popularity and prosperity of Unix that the C language was widely disseminated and used.

In 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.

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.

This is what is called mutual achievement.

In summary: Fearless of gains and losses, continuously improving, ultimately achieving mutual success.

1.6 How Was the First C Language Compiler Written?

Have you ever wondered how everyone uses C language or languages based on C to write compilers, then how was the world’s first C language compiler written? This is not a “chicken and egg” problem…

Looking back at the history of the C language: Thompson developed the B language based on BCPL, and Ritchie successfully developed the current C language based on B. Before C was used as a system programming language, Thompson had also used B to write operating systems. It can be seen that before the implementation of the C language, the B language was already usable. Therefore, the prototype of the first C language compiler could very well have been written in B language or a mix of B language and PDP assembly language.

We now know that the execution efficiency of the B language is relatively low, but if everything is written in assembly language, not only would the development cycle be long and maintenance difficult, but more frighteningly, it would lose the portability that high-level programming languages must have.

Therefore, early C language compilers took a clever approach: first, an assembly language compiler for a subset of C language was written, and then this subset was used to recursively complete the full C language compiler.

The detailed process is as follows: first create a subset of the C language with only the most basic functions, called C0 language, which is simple enough to be directly implemented in assembly language. Based on the existing functions of C0, design another subset of the C language, C1 language, which is more complex than C0 but still incomplete, and develop a compiler for C1 language using C0. On the basis of C1, design another subset of the C language, C2 language, which is more complex than C1 but still not complete, and develop a compiler for C2 language… until CN, where CN is powerful enough to develop a complete C language compiler. As for the value of N, it depends on the complexity of your target language (in this case, the C language) and the programming ability of the programmer. In simple terms, if at some subset stage, it becomes convenient to use existing functions to implement the C language, then you have found N. The following diagram illustrates this abstraction process:

A Brief History of the Development of the C Language

https://kknews.cc/tech/bx2r3j.html Introduces a concept called “Self-Compile”, which means that for certain strongly typed programming languages with obvious self-bootstrap properties (the so-called strong type means that every variable in the program must be declared with a type before it can be used, such as C language, while some scripting languages do not have this concept), they can use a limited small subset of themselves to express themselves through a limited number of recursions. Such languages include C, Pascal, Ada, etc. For why they can self-compile, please refer to the “Principles of Compilation” published by Tsinghua University Press, which implements a compiler for a subset of Pascal.

https://zhuanlan.zhihu.com/p/136102461

This process is also evidenced in the Unix V2 version.

A Brief History of the Development of the C Language

Ken Thompson, Dennis Ritchie, and others developed the second version of Unix for the PDP-11 at Bell Labs. It extended the first version with more system calls and more commands. This version also saw the beginning of the C language, which was used to write some of the commands.

The code here is only the source to some of the commands, some of the library functions, and the C compiler. The files in c/ come from the last1120c.tar.gz tape, and form a working C compiler for Second Edition Unix.

Download link: http://minnie.tuhs.org/Archive/Applications/Early_C_Compilers/last1120c.tar.gz

The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

The code here is only the source to some of the commands, some of the library functions, and the C compiler. The files in c/ come from the last1120c.tar.gz tape, and form a working C compiler for Second Edition Unix.

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

After downloading and decompressing the source code, the directory structure is as follows:

A Brief History of the Development of the C Language

Interested friends can download it for research.

2. Comparison of BCPL, B, and C Languages

If you want to find a good way to compare programming languages, then code is the best.

2.1 Code Examples of Three Languages

Below are simple programs implemented in BCPL, B, and C languages: the program adds three numbers a, b, c, and assigns the result to sum, finally printing the total.

2.1.1 BCPL Language Example

BCPL: https://zh.wikipedia.org/wiki/BCPL

GET "libhdr"

LET start() = VALOF
{ LET a, b, c = 1, 2, 3

    sum := a + b + c
    writen(sum)
}
  • LET declares a variable
  • := is the assignment symbol. Go also has this symbol, which indicates local variables within a function. Interestingly, the original father of the B language, Ken Thompson, changed the := symbol to =. Now, as one of the fathers of the Go language, he has brought back the := symbol (a fateful return~).

In the transition from BCPL to B, it was decided to use the single character = instead of the assignment :=

Other fiddles in the transition from BCPL to B were introduced as a matter of taste, and some remain controversial, for example the decision to use the single character = for assignment instead of :=. Similarly, B uses /**/ to enclose comments, where BCPL uses //, to ignore text up to the end of the line. The legacy of PL/I is evident here. (C++ has resurrected the BCPL comment convention.) Fortran influenced the syntax of declarations: B declarations begin with a specifier like auto or static, followed by a list of names, and C not only followed this style but ornamented it by placing its type keywords at the start of declarations.

https://www.bell-labs.com/usr/dmr/www/chist.html

2.1.2 B Language Example

A TUTORIAL INTRODUCTION TO THE LANGUAGE B: https://web.archive.org/web/20070807110157/http://cm.bell-labs.com/cm/cs/who/dmr/btut.html

Structure of B language

main() {
    -- statements --
}

newfunc(arg1, arg2) {
    -- statements --
}

fun3(arg) {
    -- more statements --
}

B language code example

main() {
  auto a, b, c, sum;

  a = 1; b = 2; c = 3;
  sum = a+b+c;
  putnumb(sum);
}
  • The statement auto ... is a declaration, defining the local variables to be used within the function
  • putnumb is a library function with parameters that will print a number on the terminal
2.1.3 C Language Example
#include <stdio.h>

void main(){
  int a,b,c,sum;
  
  a=1; b=2; c=3;
  sum = a+b+c;
  printf("%d", sum);
}

2.2 Differences Among the Three Examples

From the above examples, we can see the differences among the three:

  1. The C language syntax is closer to the B language
  2. BCPL and B languages are both untyped languages, using word/cell to represent a fixed-length bit. The C language is typed

There are some points you might be interested in:

  • ++ and -- symbols were invented by Thompson
  • && and || were introduced in the C language

Notes:

  1. I searched for a long time and only found some code snippets of BCPL and B languages; I don’t know if they can run ^_^
  2. If you want to know the specific differences among the three, I recommend reading Dennis Ritchie’s article on “The History of the C Language”.
  3. BCPL and B languages have also undergone several iterations (because many different writing styles can be found in the code snippets found online. For example, the B code snippets found on Wikipedia differ from those found in earlier versions of the Unix kernel. I personally speculate that this is a version issue, with different writing styles in different versions).
  4. The C language is closer to the B language, or rather, it has continuously added many new features based on B (throwing out two questions: 1. Why didn't Ritchie name it B++ like C++? 2. Why did C++ use two plus signs instead of one, calling it C+? Welcome to leave comments if you have a big enough imagination!)
  5. If any experts find issues with the above code snippets or know how to run them, feel free to communicate privately.

3. Why Was C Language Chosen in History?

In the late 1960s, research on computer systems at Bell Labs entered a prosperous period. The Multics project, a collaboration between MIT, General Electric, and Bell Labs, ended in failure (around 1969). It was during this period that Ken Thompson began writing a replacement for Multics, hoping to construct a comfortable computing system (which is Unix). Later, when writing the first version of Unix, he felt that a new system programming language was needed on Unix, so he created the B language. The B language is an untyped C, to be precise, the B language is what Thompson squeezed BCPL into 8K of memory, filtered through his own brain.

Due to some issues with the B language, it was only used to write some command tools. Coincidentally, during this period, Ritchie redesigned and improved the B language, leading to the birth of the C language.

By 1973, the C language was basically complete, and from the perspective of language and compiler, it was sufficient for Thompson and Ritchie to use C to rewrite the Unix kernel. Later, Unix gradually became popular in some research institutions, universities, and government agencies, which in turn promoted the development of the C language.

In 1978, the book “The C Programming Language” written by K&R was published, further promoting the popularity of the C language.

In summary: the right time, the right place, the right people, and the right tools (the relationship between Unix and the C language is somewhat like that between GNU and the Linux kernel, both achieving mutual success).

4. Standard C Library and Code

After several iterations, the C language and its standards have become what we see today. Its standard specifies many C standard libraries, and different systems have their own code implementations.

Of course, the Linux kernel also has code that implements the standard C library, let’s appreciate its beauty together.

4.1 Standard C Library

ANSI C includes a total of 15 header files. In 1995, Normative Addendum 1 (NA1) approved the addition of three header files (iso646.h, wchar.h, and wctype.h) to the C standard library. The C99 standard added six header files (complex.h, fenv.h, inttypes.h, stdbool.h, stdint.h, and tgmath.h). The C11 standard added another five header files (stdalign.h, stdatomic.h, stdnoreturn.h, threads.h, and uchar.h).

As of now, the C standard library has a total of 29 header files:

A Brief History of the Development of the C Language

https://www.wikiwand.com/zh-sg/C%E6%A8%99%E6%BA%96%E5%87%BD%E5%BC%8F%E5%BA%93#/%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE

4.2 linux/lib/string.c

Linux kernel version: 4.18.13

Linux kernel address: https://www.kernel.org/

Below are three string processing functions strcpy(), strncpy(), strncat(). The code is from Linus Benedict Torvalds, why do I say this? Look at the header comment of the code, it still has that familiar flavor of stupid. Those who have seen the git source code should also know that there are similar comments in the git source code.

// SPDX-License-Identifier: GPL-2.0
/*
 *  linux/lib/string.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 * stupid library routines.. The optimized versions should generally be found
 * as inline code in <asm-xx/string.h>
 *
 * These are buggy as well..
 *
 * * Fri Jun 25 1999, Ingo Oeser <[email protected]>
 * -  Added strsep() which will replace strtok() soon (because strsep() is
 *    reentrant and should be faster). Use only strsep() in new code, please.
 *
 * * Sat Feb 09 2002, Jason Thomas <[email protected]>,
 *                    Matthew Hawkins <[email protected]>
 * -  Kissed strtok() goodbye
 */

// .......omit other......
// ...... here is my love code  .....

#ifndef __HAVE_ARCH_STRCPY
/**
 * strcpy - Copy a %NUL terminated string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 */
#undef strcpy
char *strcpy(char *dest, const char *src)
{
 char *tmp = dest;

 while ((*dest++ = *src++) != '\0')
  /* nothing */;
 return tmp;
}
EXPORT_SYMBOL(strcpy);
#endif

#ifndef __HAVE_ARCH_STRNCPY
/**
 * strncpy - Copy a length-limited, C-string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: The maximum number of bytes to copy
 *
 * The result is not %NUL-terminated if the source exceeds
 * @count bytes.
 *
 * In the case where the length of @src is less than  that  of
 * count, the remainder of @dest will be padded with %NUL.
 *
 */
char *strncpy(char *dest, const char *src, size_t count)
{
 char *tmp = dest;

 while (count) {
  if ((*tmp = *src) != 0)
   src++;
  tmp++;
  count--;
 }
 return dest;
}
EXPORT_SYMBOL(strncpy);
#endif

#ifndef __HAVE_ARCH_STRLCPY

#ifndef __HAVE_ARCH_STRNCAT
/**
 * strncat - Append a length-limited, C-string to another
 * @dest: The string to be appended to
 * @src: The string to append to it
 * @count: The maximum numbers of bytes to copy
 *
 * Note that in contrast to strncpy(), strncat() ensures the result is
 * terminated.
 */
char *strncat(char *dest, const char *src, size_t count)
{
 char *tmp = dest;

 if (count) {
  while (*dest)
   dest++;
  while ((*dest++ = *src++) != 0) {
   if (--count == 0) {
    *dest = '\0';
    break;
   }
  }
 }
 return tmp;
}
EXPORT_SYMBOL(strncat);
#endif

#ifndef __HAVE_ARCH_STRLCAT

// .......omit other......
// ...... here is my love code  .....

The first time I watched this code with a classmate, he said: This is what code should look like; everything else is s-h-X-t. Now looking back, when I implemented this code, I wrote a pile of things that I don’t know what they are. Sigh, code is better than code to throw~

Reading others’ code is also a form of progress and growth

5. Is C Language Still Relevant?

According to the “Records of the Grand Historian: The Biography of Lian Po and Lin Xiangru”, after being dismissed, Lian Po went to the State of Wei. The King of Zhao wanted to use him again and sent someone to check on his physical condition. Lian Po bribed the messenger, and when the messenger saw Lian Po, he was served a measure of rice and ten pounds of meat, and was armored and mounted to show he was still usable. The messenger returned to report to the King of Zhao: “General Lian Po, although old, is still good at eating, but when sitting with me, he has already lost his temper three times (a euphemism for being old).” The King of Zhao thought Lian Po was old and thus did not use him.

Having experienced decades of storms, the C language has been glorious and can be seen everywhere in this world. However, at the same time, some people may think that the C language is already in its twilight years (nearly 50 years old). Like the image below:

A Brief History of the Development of the C Language

If you really think so, then you are mistaken.

TIOBE Index for September 2020

https://www.tiobe.com/tiobe-index/

The TIOBE programming language ranking for September 2020 tells you that the C language is still sharp and remains the brilliant youth it once was.

A Brief History of the Development of the C Language

Personally, I would like to say that as long as computers are still based on the von Neumann architecture and chips are still based on physical processes, there will always be a sky for C. Because it knows the closest place to the sky (C is one of the high-level languages closest to assembly and machine language).

Let the upper-level applications change dynasties, I (the C language) remain unmoved. This is C, the C language in my heart.

Conclusion

Suddenly realizing that it is time to conclude, but still feeling that I have not said enough, this is not the most real version of her in my mind. However, I still hope that after reading this article, you can understand and become familiar with the beauty and reality of C.

A Brief History of the Development of the C Language

Finally, I want to say: no matter how many words are said, they cannot express the importance of the C language; these words are just the tip of the iceberg.

Due to my limited ability, if there are any issues or flaws, please feel free to point them out.

References

During the organization process, some references and citations are from the following links:

[1] https://www.bell-labs.com/usr/dmr/www/index.html Ritchie’s Bell Labs Homepage

[2] https://www.bell-labs.com/usr/dmr/www/chist.html History of the C Language

[3] https://www.bell-labs.com/usr/dmr/www/1stEdman.html Unix Programmer’s Manual

[4] https://www.bell-labs.com/usr/dmr/www/bcpl.html”>https://www.bell-labs.com/usr/dmr/www/bcpl.html Martin Richards’s BCPL Manual

[5] https://www.levenez.com/lang/ Computer Languages History

[6] https://www.levenez.com/unix/”>https://www.levenez.com/unix/ Unix History

[7] https://minnie.tuhs.org/cgi-bin/utree.pl The Unix Tree (you can see the source code of many old systems)

[8] https://zh.wikipedia.org/wiki/丹尼斯·里奇

[9] https://www.tiobe.com/tiobe-index/ TIOBE

[10] http://web.eah-jena.de/~kleine/history/”>http://web.eah-jena.de/~kleine/history/ Historic Documents in Computer Science

Leave a Comment