init(s, t)
char s[]; {
would be equivalent to: int init(char s[], int t) {
This still works with modern compilers.I'd be interested if anyone has any more info about this:
waste() /* waste space */
{
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
}
Found in last1120c/c10.cA second, less noticeable, but astonishing peculiarity is the space allocation: temporary storage is allocated that deliberately overwrites the beginning of the program, smashing its initialization code to save space. The two compilers differ in the details in how they cope with this. In the earlier one, the start is found by naming a function; in the later, the start is simply taken to be 0. This indicates that the first compiler was written before we had a machine with memory mapping, so the origin of the program was not at location 0, whereas by the time of the second, we had a PDP-11 that did provide mapping. (See the Unix History paper). In one of the files (prestruct-c/c10.c) the kludgery is especially evident.
Cool to think that that waste function can still compile with todays compilers. A quick disassembly it seems to take up 751 bytes compiled on x64 using clang on O0.
It looks beautiful, almost like a scripting language. No monster type signatures like
const std::foo_bar<boost::blah_ptr<const xyz::bar::Bar&, baz::Baz>>&http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html
Which led me to here:
http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
Where, if you take the time, you will find a wonderful story, upon completing, you will probably know more about the early embryonic history of C then 95% of your peers.
(Spoiler - We start with BCPL, then Move to B - it's left as an exercise to determine how we originally compiled BCPL)
Oh how our minds play tricks on us!
The first version of Go started with B: http://code.google.com/p/go/source/detail?r=f6182e5abf5e
The second revision was converted to C: http://code.google.com/p/go/source/detail?name=f6182e5abf5e&...
The third to Draft-Proposed ANSI C: http://code.google.com/p/go/source/detail?name=f6182e5abf5e&...
And the fourth to ANSI C: http://code.google.com/p/go/source/detail?name=f6182e5abf5e&...
To compile a C compiler, you don't need a full-blown C compiler. For instance, I bet floats and doubles are not used. Therefore, you can write a barebones proto-C compiler in whatever language you have available and use it to bootstrap your compiler. Rinse and repeat.
I worked on Univac 9400s. We received the O/S in source code form (Assembly) on tape. We ran it through a parametizer (PROC), compiled the resulting source, and that's what the customer ran with.
You haven't lived until you've stepped through your code one instruction at a time, displaying op codes and raw binary data on the maintenance panel lights.