conversion of short to unsigned it

Mike Wescott wescott at ncrcae.UUCP
Fri Mar 22 00:56:18 AEST 1985


The motivation for the original posting on this question, (which I belatedly
canceled so as to make a more reasoned submission), is an inconsistency in
the C-compiler concerning the conversion of short to unsigned int.  Both
SYsVr2 and 4.2BSD compilers exhibit the inconsistency:

	unsinged int ui;
	unsigned short us;
	short s;
	   .
	   .
	   .
	s = -3;
	us = -3;
	ui = s;
	printf("%x %x %x\n", ui, us, s);

prints
fffffffd fffd fffffffd
as expected.  However the comparison 

	if ((unsigned int)s == us) printf("OOPS\n");

prints OOPS meaning that fffffffd == 0000fffd !!!
The code generated for the comparison is a

	cmpw	_s, _us

No conversion.  K&R confused me with the "otherwise" phrase
in the section on arithmetic conversions.  The version of the C standard
was not much more help but it eventually became clear that the code for
the comparison is improperly generated.  The short should be sign extend
and the unsigned short should be padded with 0's on the left and the
compare should be a cmpl.

The piece of code that brought this to light was SysVr2's uucp code in
pk0.c/chksum(), where the code

	register short sum;
	register unsigned short t;
	    .
	    .
	    .
	if ((unsigned)sum <= t) {
	    .
	    .
	    .
"broke" on a new compiler.  Explicitly casting to "unsigned short" fixed
the checksum calculation (i.e. made uucp talk to our vax).  Looking
at the code generated on the vax pointed up the inconsistency.

BTW, the cast (unsigned) implies (unsigned int), and the vax C-compiler
produces a cmpw for both casts.

	Mike Wescott
	NCR Corp.
	ncrcae!wescott



More information about the Comp.lang.c mailing list