[comp.lang.c] Signed to unsigned comparison

PLS@cup.portal.com (Paul L Schauble) (03/23/91)

What should a compiler do with the comparison in this example:

    unsigned int a;

    a = 5;
    if (a > -1) ....

Since all of the possible values for a are positive, the comparison 
should always be true and the compiler should process this as though it
were written
    if (1)

Correct? Does the standard address this case?

    ++PLS

henry@zoo.toronto.edu (Henry Spencer) (03/24/91)

In article <40472@cup.portal.com> PLS@cup.portal.com (Paul L Schauble) writes:
>What should a compiler do with the comparison in this example:
>    unsigned int a;
>
>    a = 5;
>    if (a > -1) ....

The infamous "usual arithmetic conversions" apply.  The -1 is converted to
`unsigned int', probably giving something like 65535 or 2147483647, and
then the comparison is done, probably not giving the result you expect.

What a compiler *should* do is give you a warning about this.
-- 
"[Some people] positively *wish* to     | Henry Spencer @ U of Toronto Zoology
believe ill of the modern world."-R.Peto|  henry@zoo.toronto.edu  utzoo!henry

torek@elf.ee.lbl.gov (Chris Torek) (03/24/91)

In article <40472@cup.portal.com> PLS@cup.portal.com (Paul L Schauble) writes:
>What should a compiler do with the comparison in this example:
>
>    unsigned int a = 5;
>    (a > -1) ....
>
>... the comparison should always be true ...
>Correct? Does the standard address this case?

No, and yes.

The comparison of an unsigned and a signed is done by widening both
to a `common' type; the result is that

	unsigned short a = 5;
	(a > -1)

is true only if sizeof(short) < sizeof(int).  If sizeof(short) ==
sizeof(int), the `common' type is unsigned and (for a typical 2s
complement 32 bit machine) we get:

	(unsigned)5 > (unsigned)-1
	0x00000005 > 0xfffffffe
	0

If sizeof(short) < sizeof(int), the `common' type is int and we get:

	(int)5 > (int)-1
	5 > -1
	1

This is why the `unsigned preserving' semantics were the correct
choice.  ANSI C uses the `value preserving' semantics to attempt to
make the comparison (unsigned short)5 > -1 less surprising---had they
chosen unsigned-preserving semantics, it would *always* be false---but
the result is that you can never predict what your programs will do;
you are forced to include a cast.  (A proper cast gives predictable
results under both schemes.)

Note that this particular botch affects you only if you have an uncast
signed/unsigned comparison.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

henry@zoo.toronto.edu (Henry Spencer) (03/24/91)

In article <11389@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
>The comparison of an unsigned and a signed is done by widening both
>to a `common' type...

Not strictly true... as in the case originally inquired about, where no
widening is done, just a conversion.
-- 
"[Some people] positively *wish* to     | Henry Spencer @ U of Toronto Zoology
believe ill of the modern world."-R.Peto|  henry@zoo.toronto.edu  utzoo!henry

torek@elf.ee.lbl.gov (Chris Torek) (03/24/91)

In article <11389@dog.ee.lbl.gov> I wrote:
>	(unsigned)5 > (unsigned)-1
>	0x00000005 > 0xfffffffe

Oops, brain fault, that was one's complement.  The idea was right though.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (03/26/91)

In article <1991Mar24.001308.12852@zoo.toronto.edu>, henry@zoo.toronto.edu (Henry Spencer) writes:
> The -1 is converted to `unsigned int', probably giving something like
> 65535 or 2147483647, and then the comparison is done, probably not

65535 or *what*?  I don't think 31-bit ints can really be spoken of
with language like "probably".

:-), naturally....

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu