Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utcs!mnetor!seismo!nbires!hao!hplabs!ucbvax!ucbcad!pavepaws!metcalf From: metcalf@pavepaws.UUCP Newsgroups: net.micro.amiga,net.micro.atari16 Subject: C compiler bugs Message-ID: <888@ucbcad.BERKELEY.EDU> Date: Fri, 18-Jul-86 03:21:23 EDT Article-I.D.: ucbcad.888 Posted: Fri Jul 18 03:21:23 1986 Date-Received: Sat, 19-Jul-86 02:56:11 EDT Sender: news@ucbcad.BERKELEY.EDU Reply-To: metcalf@pavepaws.UUCP (Chris Metcalf) Organization: University of California, Berkeley Lines: 70 Xref: utcs net.micro.amiga:3940 net.micro.atari16:1328 I've been doing some work lately on writing machine- and compiler-independent graphics code, and as a result came up with a variety of bugs for Lattice, Megamax, and Aztec compilers (Lattice and Aztec are available both on Amiga and ST; Megamax is an ST-only phenomenon). Compiler bugs are one of the most annoying facts of life that a software writer has to live with; I thought I could spare some of you some grief by listing a few of the interesting ones I've found. Lattice: this was my favorite bug. It seems that my release of the Lattice compiler (on the Amiga, 3.03) has a very small problem in its floating- point library; if a float becomes almost equal to +/-2.000000 (in fact, if its binary is 0x40000002 or 0xC0000002) then all multiplications using it fail. Multiplying this value of -2 by itself gives -2, for example; and multiplying it by anything else gives 0. This is not a good thing for people who need even vaguely reliable floating-point math. I stumbled across this strange bug purely by chance, and it took a LONG time to track it down. Here's a piece of code to show what I mean: main() { float f; *(long *)&f = 0xc0000002; printf("%f * %f = %f!!\n", f, f, f * f); } If you get "-2 * -2 == -2!!" then your compiler is in trouble... and there aren't any easy fixes. Using double math doesn't help, since Lattice (bizarrely) casts floats to double just to multiply; the double killer-value is 0xc000000040000000. All you can do is pray your code doesn't hit it. Mine does, with dismal regularity; Lattice users lose. Megamax: my version (1.0) has a little float-math trouble as well. If you have some expression whose value is 0, and negate it and assign it to a variable, hey presto! its value is -2. Thus "float a = 0; a = -a" will set a to -2. (Compiler bugs seem to like this number..) This problem at least has a workaround; if you say "a = 0 - a" the problem doesn't appear. Also a problem, and equally annoying, is that floating-point comparisons don't work very well. Try, for example, "printf("%d\n",2.0<-1.0)". It prints 1. This (you may notice) is not correct. I fixed this on an ad hoc basis in my code by checking -2 > 1.0 (which does work). Aztec 3.20a: when I had fixed the Megamax bug, I wiped the sweat from my brow and turned to my trusty Aztec Manx compiler to recompile the altered source. What should I find but the program failing again! After more work, I finally traced it down to the expression "a[i] = 0 - b[i]" (yes, one of the lines I had "fixed" so Megamax would accept it...). It seems that the Aztec compiler has trouble with expressions of this form, where one subscripted float is subtracted from a constant and assigned to another subscripted float (it may be a more general problem, but variable subscripts at least are required). The result is that b[i] is ignored, and a[i] is assigned the constant. Why this is I don't know; my knowledge of 68000/68881 is weak but the assembler output looked ok to me. The workaround for this one turned out to be assigning "0 - b[i]" to an intermediate variable, and assigning that to a[i]. So it goes... nobody can do float math right. Another smaller bug fell out after I had all of these in order; one of the Lattice compiler's infamous CXERR messages (#25) resulted when compiling a perfectly innocuous piece of code. It appears that Lattice has trouble accepting more "register" declarations than it has registers! Rather than ignoring subsequent register declarations, it starts handing out non- existent registers. Combining my knowledge of CXERR meanings (from an Amiga Mail issue) with the fact that Lattice only allows four address and six data register values let me fix that one, but it was an annoyance. (If anyone wants the list of CXERR meanings, let me know and I'll type them in.) Hopefully this will help somebody, somewhere. Five compiler bugs in two days was a little too much, and hopefully some programmer can come a little closer to maintaining his sanity as a result of this posting. Good luck... Chris Metcalf (metcalf@yale.ARPA) ...!decvax!yale!metcalf metcalf@yalecs.BITNET ...!ihnp4!hsi!yale!metcalf