From mboxrd@z Thu Jan 1 00:00:00 1970 To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> In-reply-to: Your message of "Thu, 22 Apr 2010 21:32:36 +0200." <20100422193236.GA2388@polynum.com> References: <20100422175033.GA6247@polynum.com> <87d97130a41364706523e641fe0dd372@plan9.bell-labs.com> <20100422193236.GA2388@polynum.com> From: Bakul Shah Date: Thu, 22 Apr 2010 13:07:40 -0700 Message-Id: <20100422200740.49F7D5B73@mail.bitblocks.com> Subject: Re: [9fans] BUG!!! in Plan9 compiler! Topicbox-Message-UUID: 0c558d46-ead6-11e9-9d60-3106f5b1d025 On Thu, 22 Apr 2010 21:32:36 +0200 tlaronde@polynum.com wrote: > On Thu, Apr 22, 2010 at 03:08:40PM -0400, geoff@plan9.bell-labs.com wrote: > > What type is `smallnumber'? > > typedef unsigned char smallnumber; ^^^^^^^^ Aha! > translated from Pascal: > > small_number=0..63; IIRC in C89 integer promotions rules changed. See 6.3.1.8 (Usual arithmetic conversions) [Otherwise,]the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands: If both operands have the same type, then no further conversion is needed. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type. >>>> Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. Try this on both gcc and 8c (with suitable changes): #define N(i) atoi(v[i]) int f(int x, int y, unsigned char z) { return (x + y + z) / 2; } int main(int c, char**v) { printf("%d\n", f(N(1), N(2), N(3))); } And see what you get. I suspect you can safely change smallnumber to a signed char and most likely this particular problem will go away.