From mboxrd@z Thu Jan 1 00:00:00 1970 From: jnc@mercury.lcs.mit.edu (Noel Chiappa) Date: Mon, 27 Oct 2014 10:48:33 -0400 (EDT) Subject: [TUHS] speaking of early C compilers Message-ID: <20141027144833.536A618C0A5@mercury.lcs.mit.edu> > From: Jason Stevens > has anyone ever tried to compile any of the old C compilers with a > 'modern' C compiler? > ... > How did any of this compile? How did this stuff run without clobbering > each-other? As Ron Natalie said, the early kernels are absolutely littered with all sorts of stuff that, by today's standards, are totally unacceptable. Using a variable declared as an int as a pointer, using a variable declared as a 'foo' pointer as a 'bar' pointer, yadda-yadda. I ran (tripped, actually :-) across several of these while trying to get my pipe-splicing code to work. (I used Version 6 since i) I am _totally_ familiar with it, and ii) it's what I had running.) For example, I tried to be all nice and modern and declared my pointer variables to be the correct type. The problem is that Unix generated unique ID's to sleep on with code like "sleep(p+1, PPIPE)", and the value generated by "p+1" depends on what type "p" is declared as - and if you look in pipe.c, you'll see it's often declared as an int pointer. So when _I_ wrote "sleep((p + 1), PPIPE)", with "p" declared as a "stuct file pointer", I got the wrong number. I can only speculate as to why they wrote code like this. I think part of it is, as Brantley Coile points out, historical artifacts due to the evolution of C from (originally) BCPL. That may have gotten them used to writing code in a certain way - I don't know. I also expect the modern mindset (of being really strict about types, and formal about coverting data from one to another) was still evolving back then - partly because they often didn't _have_ the tools (e.g. casts) to do it right. Another possibility is that they were using line editors, and maintaining more extensive source is a pain with an editor like that. Why write "struct file *p" wnen you can just write "*p"? And of course everyone was so space-concious back then, with those tiny disks (an RK05 pack is, after all, only 2.5MB - only slightly larger than a 3.5" floppy!) every byte counted. I have to say, though, that it's really kind of jarring to read this stuff. I have so much respect for their overall structure (the way the kernel is broken down into sub-systems, and the sub-systems into routines), how they managed to get a very powerful (by anyone's standards, even today's) OS into such a small amount of code... And the _logic_ of any given routine is usually quite nice, too: clear and efficient. And I love their commenting style - no cluttering up the code with comments unless there's something that really needs elucidation, just a short header to say, at a high level, what the routine does (and sometimes how and why). So when I see these funky declarations (e.g. "int *p" for something that's _only_ going to be used to point to a "struct file"), I just cringe - even though I sort of understand (see above) why it's like that. It's probably the thing I would most change, if I could. Noel