From: meulenbr@ce.philips.nl (Frans Meulenbroeks)
Subject: Re: ACK ANSI Compiler
Organization: Philips Consumer Electronics, Eindhoven
Date: Tue, 26 Jan 1993 12:30:07 GMT

newton@monty.apana.org.au (Mark Newton) writes:

>meulenbr@ce.philips.nl (Frans Meulenbroeks) writes:
>> newton@monty.apana.org.au (Mark Newton) writes:
>> [...]
>> >The 68000 ACK compiler has bugs - BAD bugs. [...]
>> 
>> ...
>> 
>> I challenge you to send a bug list to the net to prove your statement!

>Oh dear.  He wants me to enumerate them <sigh>

>A large number of MINIX programs which wouldn't work with the ACK
>compiler have compiled flawlessly on my system (and a number of other
>68000 MINIX systems which I am acquainted with) with c68.

>I'm not talking about programs that came with the MINIX distribution;
>they'd be expected to work properly when compiled with ACK.  But, third
>party packages like Minicom 1.2, FvK's UUCP, Nethack 1.2e, the curses
>package on plains, and parts of Elm 2.4 wouldn't work correctly with
>ACK on any of the Amiga MINIX systems I know.  And fixing them was as
>simple as unarchiving the sources and recompiling them with c68.

This is not necessary the fault of the compiler. I've compiled a lot of
programs using the K&R compiler, and if the programs do not run then 
almost always this ast because the code is sloppy, not because the
compiler is bad.

The basic problem is that with ACK for 68000 the assumption that
sizeof(int)==sizeof(char *) does not hold. With ACK/68000 ints are 2
bytes and pointers are 4. There is a lot code floating around which
thinks it is safe to stuff an pointer into an int. Heck even the unix v7
nroff which I ported to 68000 about 9 years ago suffered from this
problem.

Note however that C never ever requires ints and pointers to be of the
same size.

The following things typically cause problems:
1) the source code does not include a forward declaration for a function
   returning a pointer (e.g. malloc). If you call such a function and
   the compiler hasn't seen a declaration for the function, it assumes
   that it is a function returning int. With K&R ack this means that you
   get a 16 bit value, not a 32 bit one. Even if you assign this value
   to a pointer it still has the wrong contents. If you use this pointer
   you are not writing into the memory you allocated, but into low
   memory, thus destroying the operating system code (which is caused by
   the fact that 68000 systems do not tend to have an MMU, which can
   give protection for this).
   If c68 has 16 bits int and still returns a 32 bit value if no
   prototype is present c68 is broken (although it does by accident what
   you wanted it to do).
2) parameters are not passed properly. If, with a K&R compiler you pass
   0 as a parameter to a function on a place where a pointer is expected,
   then only 2 bytes are pushed onto the stack while for passing a
   pointer 4 bytes are pushed. If the caller only gives 2 bytes, while
   the callee expects 4, then the callee is going to get faulty data.
   possible fixes are: add an explicit cast to the pointer
		       use an ansi compiler an prototypes
		       use a compiler where sizeof(pointer)==sizeof(int)
3) The program uses arrays > 64k. Out of my head I'm not sure if a K&R
   compiler may limit the size of an array. I believe ansi will.
   anyway, this is the most irritating limitation I encountered.
4) dereferencing NULL pointers. On an amiga maybe this is possible, but
   on an atari it definitely isn't. Code which dereferences a NULL
   pointer IMHO is broken.

If c68 does not have problems with this then either pointers and ints
have the same size, or it is an ansi compiler.

>When I say "they didn't work correctly," I don't mean that they'd just
>dump core and squirt an error message onto the console.  I mean that
>they'd crash the entire machine and necessitate a reboot.

The fact that the machine crashes is because there is no protection
hardware. Any job can write everywhere in memory causing other programs
or the kernel to crash.

>The most common kind of constructs which would cause such crashes were
>operations on strings declared with constant initializers:

>  char *foo = "this will crash my computer when I use strcpy() on it!";

>(no, it wouldn't do it in every situation; it was most insidious, and
>spending time with debuggers to work out the exact sequence of instructions
>that would cause a crash didn't do a whole lot of good for this little
>black duck.  I've never claimed to be an assembly language guru anyway
>:-)

It depends on how you strcpy it. If you use the return value of strcpy
and didn't declare the function, then, on a 68000 system without mmu, 
it is highly likely that the system crashes. The compiler is not to
blame for the fact that your code is wrong.
If you still think the compiler is doing something wrong there then
please mail me a *small* program demonstrating the problem. 

>I spent many an evening going through errant sources and changing them
>to something like this:

>   char foo[size_of_the_damned_string];
>   strcpy(foo, "this will not crash my computer...");

>to prevent lockups.

>(not to mention the lockups that bar = time() would cause when time()
>would try to write its current timer value to a pointer argument that
>hadn't been supplied - bar = time(NULL) was the simple fix for that.
>bar = time() doesn't crash at all when c68 is used over the same source
>code).

If bar = time() does not crash under c68, then you have been lucky.
Time is a function with a pointer as parameter. So calling 
bar=time() is just not valid. The time function still gets a parameter
from the stack (which is not there so essentially it is getting garbage).
By sheer luck your code works with c68.
By the way:
bar = time(0) also won't do the job with a K&R compiler since 0 is not a
pointer and time requires a pointer argument. 
bar = time((char *)0) is ok, since then 0 is casted to a pointer.
If you have full ansi include files, the proper way to do this
is bar = time((time_t)0) or probably bar = time_t(NULL).

>Now, I acknowledge that the problem was as much with the kernel as with
>the compiler, but all of those hassles dried up the instant I stopped
>using ACK and switched to c68.  Magic, eh?  Now my system stays up for
>days on end without problems, even when I'm doing heavy development work.

>Even now, if I accidentally type "cc" instead of "cc68" to compile
>something I've been working on, and run it without realizing it, crashes
>occur.  Compile it with c68 and bingo!  Flawless operation.

Hm. I'm still not convinced that K&R ACK is that broken.

>Everyone who's been in this newsgroup for more than a few months knows
>that the K&R ACK compiler had bugs, and the 680x0 version was worse than
>the Intel version.  As far as I can tell, the only reason it isn't talked
>about much these days is because all the people who know what has been
>causing their system crashes for all these years have switched over to
>c68.  I'm not sure if the Walker brothers realize what a godsend that
>compiler has been to me and every other MINIX user I know.

I've been around more often than most of you, but I haven't seen that
much bug reports of the K&R/68000 compiler. I've seen a lot of sloppy
code though.

>End of diatribe.

>For corrobative purposes, could anyone out there running stock-standard
>v1.5.10.1 or 1.5.10.2 Amiga MINIX please try an experiment for me?  ftp
>the curses package from plains (I _think_ it's on plains!), compile it
>up, and try to run the demo that comes with it.  I'd recommend that you
>type "sync" before you try it out; The system won't stay alive for long
>enough to flush your buffer cache :-)

I can't ftp so I cannot test this. However, most implementations of
curses I've seen were sloppy. Long ago I posted some diffs for BSD
curses to allow using them with ack cc.

>Then rebuild it with c68 v4.x and run the demo again.  Magic!

>(then compile your kernel with it - does the 30k decrease in size
>surprise you?)

No. I don't think anyone on the net ever said that ACK/68000 did 
produce compact code. If you want compact code and have some
megabytes to spare go for gcc.

--
Frans Meulenbroeks		Philips Research Laboratories
preferred email address: 	meulenbr@prl.philips.nl