🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.dec
Article #5548

Re: BUG is MIPS cc for "?" operator

#5548
From: Dan Schuh
Date: Thu, 01 Feb 1990 16:04
62 lines
2925 bytes
In <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 experience ...
( relatively long example deleted, excerpt below)


This is not actually a bug, though I'm sure many have been and will
continue to be bitten by it.  It's actually an ansi-ism in the mips C
compiler.  The root of the problem is that sizeof is treated as
unsigned by the mips C compiler..  K&R I listed sizeof as a signed
value, but K&R II and ansi are both clear  in making it an unsigned
value.  This can result in unexpected results in comparisions as the
unsigned-ness of sizeof propagates through expressions, under the
normal c rules.

In the first 'wrong' result instance in your code, you have
#define MAX(A,B)        ((A)>(B))?(A):(B)
#define BITS_PER_INT    (sizeof(int)*8)
...
	int high, low;
	high= 19;
...
	low = MAX(0, high-BITS_PER_INT+1);

and low ends up unexpectedly as -12 instead of 0.  BITS_PER_INT is an
unsigned expression due to the presence of sizeof, and therefore
high-BITS_PER_INT+1 also becomes unsigned, turning into something
undeniably greater that zero.  When the value of (B) gets assigned to
low, it is coerced back into a sized value and becomes -12; but in its
unsized incarnation it couldn't possibly be less than 0. 

Note that in all the working examples, the comparable expressions
do not contain sizeof, vis:

#define BITS_PER_INT 32
low = MAX(0, high-BITS_PER_INT+1);

When I first came across this I was pulling out hair as I looked at the
assembler output of the offending code compared to the dissassembled
output of the same code in the debugger; I had written something like

if ( 0 < ( value - sizeof(something)) ....

The assembler output  at the relevant point in the expression jump code was:

bgeu <dest>

while the disassembled object said

br  <dest>

So I was running around telling people bizarre things were happening
in the mips linker/ backend optimizer or something, until enlightenment
dawned and I realized that a branch greater than or equal unsigned (bgeu)
was indeed a branch.

Cheers, Dan, schuh@cs.wisc.edu
Technical Details
Message-ID: <9652@spool.cs.wisc.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uwm.edu!uwvax!whey.cs.wisc.edu!schuh
References: <21624@pasteur.Berkeley.EDU>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uwm.edu!uwvax!whey.cs.wisc.edu!schuh
From: schuh@whey.cs.wisc.edu (Dan Schuh)
Newsgroups: comp.sys.dec,comp.sys.mips
Subject: Re: BUG is MIPS cc for "?" operator
Keywords: compiler, MIPS
Message-ID: <9652@spool.cs.wisc.edu>
Date: 1 Feb 90 16:04:17 GMT
References: <21624@pasteur.Berkeley.EDU>
Sender: news@spool.cs.wisc.edu
Organization: U of Wisconsin CS Dept
Lines: 62