[comp.lang.c] unsigned short vs. negative constant

ado@elsie.UUCP (Arthur David Olson) (05/04/87)

Thanks to everyone who replied to replied to my question about what the code
	#include "stdio.h"

	main()
	{
		unsigned short	us;

		us = ~0;
		(void) printf("%d\n", us == -1);
	}
should print on systems where sizeof short < sizeof int,
and what it actually does print on various systems.  The scoop:

*	Some systems simply print 1,
	including Elsie herself (a VAX 11-750 running MORE/bsd 4.3),
	a VAX 11-780 running 4.3 BRL UNIX, and an Ultrix 1.2 system.
*	Other systems systems simply print 0, including KCC on TOPS-20,
	an AT&T 3B5 running System V Release 2.0.1 3B5 Version 2,
	an a "moto '030 machine running System V.2."
*	The latest Sun systems print 1; issuing a warning during compilation.
*	A Concurrent system prints 0; it issues a warning during compilation.
	Sun systems may do this in the future.
	Saber-C prints 0; it issues a warning.
*	K&R can't be used to resolve the issue, since it predates unsigned
	shorts.
*	The consensus of opinion is that under X3J11's "value-preserving"
	widening rules, the program should print 0.

The moral of the story: folks who maintain the various versions of lint may
want to have it look for and warn about such code, at least when lint is run in
"check portability" mode.
-- 
	UUCP: ..seismo!elsie!ado	   ARPA: elsie!ado@seismo.CSS.GOV
	     Elsie and Ado are trademarks of Borden, Inc. and Ampex.

msb@sq.UUCP (05/09/87)

Arthur David Olson (ado@elsie.UUCP) writes:
> Thanks to everyone who replied to replied to my question about what the code
> 	#include "stdio.h"
> 	main()
> 	{
> 		unsigned short	us;
> 		us = ~0;
> 		(void) printf("%d\n", us == -1);
> 	}
> should print on systems where sizeof short < sizeof int,

But he didn't include some points from my reply, which I think are worth
posting, so I am disregarding his Followup-to and posting this.
(Arthur: did you get my mail at all?)

The first thing is that there is no such thing as a "negative constant"
in C.  Both "~0" and "-1" are int constant-EXPRESSIONS.  They have the same
value on 2's complement machines, but will differ on most or all other
types of machines.  (YES, there are non-2's-complement machines running C.)
This, then, is another nonportability in the above code... and remains one
under the Draft ANSI Standard, unlike the  unsigned short / int interaction.

The second thing is that although it's true that...
> *	K&R can't be used to resolve the issue, since it predates unsigned
> 	shorts.
...nevertheless one may make an inference by considering the interaction
of longs with unsigned ints, which IS specified in K&R.  In THAT case the
corresponding code must print 0.

And a final note.  I hate it when people just post and say "this is the way it
works on MY machine", but since I was posting anyway, this is the way it works
on my machine.  sq is a Sun running SunOS 3.0, and it prints 1 without a
warning.  I guess we don't have the "latest" system, since Arthur said...
> *	The latest Sun systems print 1; issuing a warning during compilation.

Mark Brader, Toronto	    { decvax | ihnp4* | watmath | ... } !utzoo!sq!msb
		or via { hplabs | lll-crg | ... } !seismo!mnetor!utzoo!sq!msb
*Avoid -- overloaded.			or via		 decwrl!utcsri!sq!msb