Xref: utzoo comp.sys.dec:2566 comp.sys.mips:457 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jarthur!bridge2!mips!gumby!lai From: lai@mips.COM (David Lai) Newsgroups: comp.sys.dec,comp.sys.mips Subject: Re: BUG is MIPS cc for "?" operator Keywords: compiler, MIPS Message-ID: <35381@mips.mips.COM> Date: 2 Feb 90 09:02:34 GMT References: <21624@pasteur.Berkeley.EDU> Sender: news@mips.COM Reply-To: lai@mips.COM (David Lai) Followup-To: comp.sys.dec Organization: MIPS Computer Systems, Sunnyvale, CA Lines: 83 In article <21624@pasteur.Berkeley.EDU> jac@modoc.berkeley.edu (Gordon Jacobs) writes: >The program below demonstrates various uses of the "?" >selection operator in c that seem to not work correctly on >a DEC3100 running Ultrix3.1. This has also been compiled >on a unit running a test version of Ultrix4.0 with the >exact same results. This seems like a fairly major bug and >it could affect much old software. Has anyone experienced >this or confirmed it?? The test program shows version which >work and don't work... > >Thanks, >Gordie Jacobs, UCB >------------------ cut here -------------------------------------- > >#define MAX(A,B) ((A)>(B))?(A):(B) > >#define BITS_PER_INT (sizeof(int)*8) >#define INTS_PER_BUS ((int)(20/BITS_PER_INT)+1) > >main () { > > int high, low; > int bits_per_int, sizeofint; > > printf("INTS_PER_BUS=%d BITS_PER_INT=%d\n", > INTS_PER_BUS, BITS_PER_INT); > > bits_per_int= BITS_PER_INT; > sizeofint= sizeof(int); > > high= 19; > > /* All of these compute the wrong answer (-12 instead of 0) */ > low = MAX(0, high-BITS_PER_INT+1); > low = (0>(high-BITS_PER_INT+1))?(0):(high-BITS_PER_INT+1); > low = MAX(0, high-sizeof(int)*8+1); > low = (0>(high-sizeof(int)*8+1))?(0):(high-sizeof(int)*8+1); > > /* Works: > #define BITS_PER_INT 32 > low = MAX(0, high-BITS_PER_INT+1); > */ > > /* Works: > low = MAX(0, high-sizeofint*8+1); > */ > > /* Works: > low = MAX(0, low=high-BITS_PER_INT+1); > */ > > /* Works: > low = (0>(high-bits_per_int+1))?(0):(high-bits_per_int+1); > */ > > /* Works: > low = (0>(high-32+1))?(0):(high-32+1); > */ > > /* Works: > low = high-BITS_PER_INT+1; > low = MAX(0,low); > */ > > printf("high=%d low=%d MAX(0,-12)=%d\n", high, low, MAX(0,-12)); >} The problem is the sizeof() operator is unsigned, therefore the expression of the form (int) - (unsigned) + (int) yields an unsigned result. This result just happens to be a very large number which cannot accurately be represented by an int. This number is assigned to an int, which causes the upper bit to be treated as a sign bit, and the value appears to be -12. A quick fix is to do #define SIZEOF(x) ((int)sizeof(x)) and to use SIZEOF instead of sizeof() in the program. -- "What is a DJ if he can't scratch?" - Uncle Jamms Army David Lai (lai@mips.com || {ames,prls,pyramid,decwrl}!mips!lai)