ed@mtxinu.UUCP (05/05/84)
As an example of how not to write code, csh is unparalleled.
When porting it to Amdahl's UTS, I discovered that, in addition
to the way it looks inside, it depends on the DEC architecture!
In particular, it assumes that the stack grows down from the
high end of the virtual address space, and that the heap
grows from the low end. On an IBM-architected machine, this
is certainly not the case.
What csh does that depdnds on the architecture is this. There
is a routine that is called to free a piece of memory. The
memory may have been obtained through alloc(), or it may be
on the stack. It it's on the stack, then freeing it is a disaster,
and the routine doesn't do the free. How, you ask, does
this routine determine if some random piece of memory is
on the stack or in the heap? Consider the following
whereis(p)
char *p;
{
if((char *) &p < p)
printf("stack\n");
else
printf("heap\n");
}
This will correctly determine on a VAX, PDP11, 68000, 16032, ...
where the memory pointed to by p lies. On an IBM-type machine,
it will produce arbitrary results, depending on the size of
the program and the call sequence. (Actually, I suppose, a C
compiler could be written for IBM architectures that would
keep the stack at the top of memory, but they would be terribly
inefficient. Not to mention that the operating system would
probably have to deal with a program that seems to be the size
of the full virtual address space - I expect that it would
allocate paging space for the entire virtual size, sparse or no.)
Of course, just deciding that the memory is in the heap isn't
really enough to know that it's safe to free() it, but in the
case of csh it works. (At least most of the time. I wonder how
many of the lurking bugs are due to this oddness.)
--
Ed Gould
ucbvax!mtxinu!ed