|
|
On 30 avr, 00:53, Keith Thompson <ks...@xxxxxxx> wrote:
> Francois Grieu <fgr...@xxxxxxxxx> writes:
> > one of my C compiler (Keil C51) evaluates the constant expression
> > 1<<(1?1:1) < 0x9999
> > to the value 0 [typo fixed]
>
> > // this returns 0, much to my surprise
> > unsigned char bug4_a(void)
> > {
> > return 1<<(1?1:1) < 0x9999;
> > }
>
> > Can this find a satisfactory explanation under some definition of the
> > C language ?
>
> The behavior is inconsistent with the C standard. (If Keil C51 claims
> to conform, it's a bug; if it doesn't, it may or may not be a bug,
> depending on what, if anything, its documentation says).
It is supposed to be "a complete implementation of the ANSI standard
for the C language", without mention of version, so I guess C89. There
is a section on "Differences from ANSI C", with no relevant entries.
> I'll assume that types int and unsigned int are 16 bits.
Yes.
> 1<<(1?1:1) has the value 2 and is of type int.
Yes. 1 is signed, thus 1<<.. is.
> 0x9999 has the value 39321 and is of type unsigned int.
Yes.
> The "usual arithmetic conversions" are applied to the operands of "<".
> This converts the left operand, 2, from int to unsigned int.
Thanks. That was the part I'm never sure in on standards before C99.
> So the expression 1<<(1?1:1) < 0x9999 is equivalent to 1U < 39321U,
> which yields the int value 1. The return statement converts this to
> unsigned char, yielding (unsigned char)1.
>
> My guess is that a bug in the compiler is causing it to do the "usual
> arithmetic conversions" incorrectly in this case. It's probably
> converting the right operand to signed int rather than converting the
> left operand to unsigned int, changing the comparison:
> (int)2 < (unsigned)39321
> to
> (int)2 < (int)-26215
> which yields 0.
Yes. However the fun thing is that the problem occurs only if
the ?: operator is used.
(int)2 < (unsigned)39321 gives 1
1<<(1?1:1)<39321 gives 0
1<<1 <39321 gives 1
(1?2:2) <39321 gives 0
> Try replacing 0x9999 with 0x7fff and 0x8000 and see what happens.
Problem disapears.
Thanks, we found a compiler bug. I'll report it.
Francois Grieu
|
|