History of C

We all betray our origins

To really understand ourselves, and others, and any given object, we must understand the history.

Let’s visit the era immediately before C so we can understand why C is the way it is.

In the beginning there were machines

PDP-1

PDP-6

They were programmed in assembly (assembler)

``` PDP-11 Assembly .globl start .text start: mov $1,r0 / r0=stream, STDOUT=$1 sys 4; outtext; outlen / sys 4 is write sys 1 / sys 1 is exit rts pc / in case exit returns

.data

outtext: <Hello world!> outlen = . - outtext


## Then along came Burroughs

Their B5000 minicomputer was the first to use a high level language to write the OS

![B5000](https://www.cs.uaf.edu/2010/fall/cs441/proj1/b5000/b5000_paper_images/b5000.jpg){fig-align="center"}

## They used an ALGOL 60 derivative (ESPOL)

``` ALGOL
BEGIN
  FILE F(KIND=REMOTE);
  EBCDIC ARRAY E[0:11];
  REPLACE E BY "HELLO WORLD!";
  WRITE(F, *, E);
END.

Project MAC sought to replace CTSS

(Mutiple Access Computer and Machine-Aided Cognition)

MIT wanted to replace the aging CTSS with a bigger, better OS, MULTICS (1964)

They wanted to use PL/I

Hello2: proc options(main);
     put list ('Hello, World!');
end Hello2;

…They made this decision before writing anything, only specified

There would be no PL/I compiler until 1966…

As you may imagine this went poorly

And Bell Labs left the Multics project in 1969.

Ken Thompson used some of the Multics ideas to implement his own OS for the PDP-7.

The prime difference, was that this would be a more simple, bottom up design, as opposed to Multics.

This was done in assembly.

The machines in question:

PDP-7

PDP-11

PDP-10

Some tools were implemented in B

main()
{
    putstr("Hello world!*n");
    return(0);
}

Which is a derivative of BCPL

GET "libhdr"

LET start() = VALOF
{ writef("Hello world!")
  RESULTIS 0
}

This was done to make things easier to write, but struggled with performance!

And thus… C

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
  printf("Hello world!\n");
  return EXIT_SUCCESS;
}

C was really meant to be “portable assembly”

The memory behavior of the machine is integral to understanding C

Features were added to C as they were needed, unlike PL/I

C gained features like structures and macro processing as they were needed by the authors to do real work (as opposed to imagined tasks)

Standardization came late and was (and still is) contentious. The image of C is dominated to this day by “undefined behaviors”

C has minimal (but not always zero) abstraction above the machine, and has been used for OS development and performance-oriented programs for the last 40+ years.

For a long time, it was hard to do as well as C.

MODULE E1 (MAIN = CTRL) =
BEGIN
FORWARD ROUTINE
    CTRL,
    STEP;
ROUTINE CTRL =
!+
! This routine inputs a value, operates on it, and
! then outputs the result.
!-
    BEGIN
    EXTERNAL ROUTINE
        GETNUM,     ! Input a number from terminal
        PUTNUM;     ! Output a number to terminal
    LOCAL
        X,          ! Storage for input value
        Y;          ! Storage for output value
    GETNUM(X);
    Y = STEP(.X);
    PUTNUM(.Y)
    END;
ROUTINE STEP(A) =
!+
! This routine adds 1 to the given value.
!-
    (.A+1);
END
ELUDOM