[comp.os.minix] PC minix compiler bug/question

dcd@tc.fluke.COM (David Dyck) (08/15/89)

I was trying to port zoo to PC minix, (so I first tried booz, the barebones 
zoo archive extractor), and I came across an expression that the
Minix compiler interprets differently than the other C compilers
I have access to.

Given
	char p[1]= {-1};
what does
	(unsigned char) *p
evaluate to?

On the Minix ibm-pc c compiler it is -1 but all other systems seem to evaluate
to 255.  
	How does you favorite compiler handle this?
	What should the correct C compiler produce?

In the following test program
------------------- cut here ------------------
char p[1]= {-1};
main()
{
printf("*p                   = %d\n", 
	*p);
printf("(unsigned char) *p   = %d\n", 
	(unsigned char) *p );
printf("* (unsigned char *)p = %d\n", 
	* (unsigned char *)p );
}
---------------- cut here -------------------

PC Minix prints out the following output

*p                   = -1
(unsigned char) *p   = -1
* (unsigned char *)p = 255

But Sun 4.0.3, Vax 4.3 BSD UNIX, and MSC 5.0.1 produce the following output:

*p                   = -1
(unsigned char) *p   = 255
* (unsigned char *)p = 255

            David Dyck
    Domain: dcd@tc.fluke.COM
     Voice: +1 206 356 5807
      UUCP: {uw-beaver,decwrl,microsof,sun}!fluke!dcd
     Snail: John Fluke Mfg. Co. / P.O. Box C9090 / Everett WA  98206

henry@utzoo.uucp (Henry Spencer) (08/16/89)

In article <10363@fluke.COM> dcd@tc.fluke.COM (David Dyck) writes:
>	char p[1]= {-1};
>what does
>	(unsigned char) *p
>evaluate to?
>
>On the Minix ibm-pc c compiler it is -1 but all other systems seem to evaluate
>to 255...	What should the correct C compiler produce?

Well, let us trace through this.  The value in the char is -1 if "char" is
signed, 255 if it is unsigned.  [We will politely ignore the possibility
of non-two's-complement representations, and the possibility that a compiler
whose "char" is unsigned might object to -1.]  *p is an "int" value, since
"char" values promote to "int" immediately in C expressions, so that gives
us -1 for signed "char", 255 for unsigned "char".  Then we cast to "unsigned
char", which gives us 255 either way by X3J11 conversion rules.  Then finally
we do the implicit expansion to "int" again, giving 255.  Older compilers
implementing signedness-preserving rules might expand "unsigned char" to
"unsigned int", but again we get 255.

There just isn't any way that an "unsigned char" should ever expand to a
negative value; something is wrong with the Minix compiler.
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

V61%DHDURZ1.BITNET@cunyvm.cuny.edu (Ronald Lamprecht) (08/17/89)

In their recent posting David Dyck and Henry Spencer discussed a ACK
compiler bug that is well known:

Perhaps PC users should read ST related articles, too !

I described 3 compiler bugs and how they can be avoided within 3 articles
in the first half of June ! There I explained that the ACK ignores
(unsigned)- casts on signed characters.

Furthermore I posted all cdiffs that are necesarry to port ZOO to Minix ST.
Why didn't you take them as a base -- you would have avoided all trouble
with the ACK compiler and would just have to surround the 64k limit.

Bitnet:  V61@DHDURZ1                               Ronald Lamprecht
UUCP:    ...!unido!DHDURZ1.bitnet!V61              Theoretische Physik
ARPAnet: V61%DHDURZ1.BITNET@CUNYVM.CUNY.EDU       (Heidelberg, West Germany)