Path: utzoo!utgpu!water!watmath!clyde!bellcore!rutgers!mailrus!cornell!batcomputer!braner From: braner@batcomputer.tn.cornell.edu (braner) Newsgroups: comp.lang.c Subject: Re: Multiplying two shorts... Summary: A funny (?) anecdote Message-ID: <5893@batcomputer.tn.cornell.edu> Date: 11 Aug 88 17:25:49 GMT References: <948@srs.UUCP> <8101@alice.UUCP> <864@l.cc.purdue.edu> Reply-To: braner@tcgould.tn.cornell.edu (braner) Organization: Cornell Theory Center, Cornell University, Ithaca NY Lines: 38 [] I ran into a related bug in Laser C on the Atari ST. The (legal) code was: struct foo *p; /* 32-bit pointers */ int n; /* 16-bit ints <<<<<<<<<<<<<<<<<<<< */ /* (In my view the right thing on a 68000) */ ... p += n; /* <<<< here was the bug */ The compiler, turns out, did the last instruction as follows: load n load sizeof(struct foo) multiply using the 68000 mulu instruction (16*16=32 bits) truncate to an int (16 bits) <<<<<<<<<< !!!!!! extend to a long (32 bits) (actually the last two were done together as ext.l d#) long-add to p Of course, for (n > 64K/sizeof(struct foo)) the address thus calculated was wrong. The ironic part of it was that the compiler had the 32 bit result right there, and had to stomp on it with the extra "ext.l"... When coding the related C expression &p[n] the same compiler did it correctly -- but slowly, as: load n extend to long load sizeof(struct foo) as a LONG constant call the long-multiply library function (32*32=32 bits) long-add result to p this time not using the perfectly adequate "mulu" machine instruction, which could be recognized as adequate since 'n' was a 16-bit int and sizeof(struct foo), a constant known at compile time, was 6 bytes (< 64K). I was forced to replace "p+=n;" with "p=&p[n];" and take the performance loss. Happy debugging! - Moshe Braner (Try debugging on a parallel machine :-)