3

I was playing around with an online PDP11 emulator (link) and was looking at the programming section of its FAQ.

It says this about programming in C on the emulator:

You need to write pre-K&R C which is quite a bit different from modern C

I believe this is referring to the version of C in use before the publication of The C Programming Language. I have tried to understand this version by reading the sparse C files I can find in the emulator's filesystem, but even simple things like declaring argc and argv have eluded me. I also can't find anything about it online.

Is there any documentation, written at the time or after the fact, on "pre-K&R" C?

  • 8
    I think they're confused, and mean pre-ANSI C. K&R is the original C. – Barmar Dec 18 '21 at 20:48
  • 1
    Is far as I rememebr no `long int` no `unsigned int` `+=` is `=+` (same other), no standard library, no preprocessor, no `#include`, no `struct` or `union` – 0___________ Dec 18 '21 at 20:49
  • 2
    @Barmar there was the pre K&R C. – 0___________ Dec 18 '21 at 20:50
  • @0___________ "No preprocessor" surprises me considering I think I saw some `#define`s in header files. Was `#define` something different back then? –  Dec 18 '21 at 20:53
  • 1
    Then you saw "late" C if you saw header files. Original first version of C did not support inclusion of files :) . Mike Lesk has implemented and added preprocessor I believe in 1974 or 5 – 0___________ Dec 18 '21 at 20:55
  • @0___________ is there any documentation available on "late C"? –  Dec 18 '21 at 20:56
  • 2
    http://mim.update.uu.se/manuals/layered/pdp11c3.pdf – 0___________ Dec 18 '21 at 20:59
  • 1
    @0___________ Oooooooo!!! Update!!! – klutt Dec 18 '21 at 21:12
  • 1
    @klutt it is modern version – 0___________ Dec 18 '21 at 21:19
  • 1
    @0___________ I just noticed update.uu.se :) – klutt Dec 18 '21 at 21:23
  • 1
    Also in "old C", variable initialization was without `=`, so *e.g.* `int i 3;`, which is why there's that cryptic C compiler diagnostic in later versions, "Error: old fashioned initialization, use =" if you forgot the semicolon after a normal uninitialized declaration. Function argument type declarations were outside of the pre-amble, *e.g.*, `int func(a, b) int a; char b; { ... }` instead of `int func(int a, char b) { ... }`. I remember that syntax still existed in the early 1980's when I was at Bell Labs, but I think the variable init changed earlier. – lurker Dec 18 '21 at 21:31

2 Answers2

6

For this sort of question, my go-to source is the archived web page of the late Dennis Ritchie:

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

From there it's one click to this early reference manual for C, written by Ritchie himself:

https://www.bell-labs.com/usr/dmr/www/cman.pdf

This is indeed "pre-K&R C", featuring anachronisms such as =+ instead of +=.

This is the same reference manual that appeared, in updated form, as Appendix A in the K&R book.

On the same page are links to several other versions of that reference manual, as well as notes about and even the source code of two early versions of Ritchie's compiler. These are pretty fun to look at, although as the page notes, "You won't be able to compile them with today's compilers".

There's a whole Stack Exchange site dedicated to questions like these: https://retrocomputing.stackexchange.com/.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
1

Steve Summit answered about where to get the documentation. So this post is intended to summarize noticeable differences from modern C

Types for function arguments were quite different. They were not specified within the parenthesis

void foo(a, b)
    int a; 
    float b;
{
    // Function body
}

No row comments, like //. Only /* */

No logical or and and. The operators && and || did not exist. The bitwise operators & and | were used instead.

=- meant the same as -=, which lead to ambiguity with for instance x=-1.

There was no void pointers. char pointers were used instead.

One could not declare variables in the for header, so one had to write:

int i=0; 
for(i=0; i<N; ++i)

= were only used for assignments and not initialization. Those were done like this: int x 3;

Implicit int. This is still valid in modern C. The difference is that no (sane) programmer is using it anymore. This:

foo 3;

is actually equivalent to

int foo = 3;

There was no const qualifier

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 2
    With the exception of `=+` and `||`/`&&`, everything you've listed was equally true of "pre-K&R C" and actual K&R (aka pre-ANSI) C. And of course there are no hard delineations here. For example, the C described in the V6 reference manual had no structs at all; C as described in K&R1 had structs that couldn't be passed or assigned; but shortly thereafter the compiler was supporting struct passing and assigning just fine. – Steve Summit Dec 18 '21 at 23:07