Akinori MUSHA wrote:
> I observed gcc 2.95.4 and gcc 3.1 interpret (or maybe optimize) the
> following code differently (CFLAGS=-O):
> 
> int main(void)
> {
>   unsigned char i = 127;
>   printf("%d\n", ((char)(i << 1)) / 2);
>   return 0;
> }
> 

Cool...

> gcc 2.95.4 says it's -1,

Promotion of operand to int; conversion to lvalue type after
the operation.

> whereas gcc 3.1 says it's 127.

Promotion of operand to lvalue type.

> On FreeBSD
> char should be signed, so I suspect it's a (optimization) bug of gcc
> 3.1 which should be fixed.  Or we'll have to do a mass audit of the
> whole src tree to check and fix the similar expressions.

Technically, I think, because of the parenthesis, that GCC 2.95 is
right, and GCC 3.1 is wrong.  Given that the conversion to "char"
is done prior to the division, it should happen first.

>From the assembly, it looks like 3.1 is treating "/2" as ">>1",
and illegally canceling out the "<<1" with the ">>1" *before* the
conversion.  Or maybe it's the conversion to int that happens on
the stack value for a %d argument to printf...

Maybe one of out C standards people can define when the conversion
is defined to occur, so we can get a real ruling.

Note that:

int main(void)
{
        unsigned char i = 127;
        printf("%d\n", (char)((i << 1) / 2));
        return 0;
}

...yields 127 on gcc 2.95, so it's definitely order of conversion
being totally screwed by gcc 3.1.

Basically, it's assuming commutability where it's not present.


> In any case, this behavior makes moused(8) return a stupid value of
> 127 when you roll the mouse wheel up under ps/2-sysmouse-intellimouse
> protocol.  Attached is a patch that makes the whole expression look
> more logical and works around the above behavior at the same time.

[ ... ]

> -           act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1))/2;
> +           act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1)) >> 1;

This is *soooooooooo* counter intuitive that it's evil!

-- Terry

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to