Re: Recent change in tcp_output.c is surely wrong

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Tue Jan 18 2000 - 11:35:27 EST


On Tue, 18 Jan 2000, Jamie Lokier wrote:

> Rogier Wolff wrote:
> > Hmm. I'm not too familiar with the exact wording of ANSI. However,
> > they usually take the road where "more accuracy in intermediates is
> > allowed", as that can normally only reduce the amount of trouble that
> > you get into when things near the limit of the size you're using.
>
> For signed types there is some flexibility, but unsigned types behave
> pretty much as N bits.
>
> > Is a compiler allowed to optimize
> >
> > a + 4 - 4
> >
> > into "a"?
>
> On a 2's complement machine that is always true anyway.
>
> > If you're right that a compiler may not extend the size of the
> > intermediates beyond the size of an unsiged int, the Alpha compiler
> > is in trouble, as it has to explicitly cater for this. Ints on Alpha
> > are 32 bits, but registers are 64 bits, so it will have to explicitly
> > clip the intermediate on:
> >
> > (a << 4) >> 4
> >
> > Usually, ANSI will take the road where the compiler writer is allowed
> > to optimize for the common case: More accuracy usually doesn't matter.
>
> For a signed int, that optimisation would be valid on an Alpha. Even in
> GCC's model. Think about what signed right shifts do. But for an
> unsigned int, it would be equivalent to `a & 0x0fffffff'.
>
> enjoy,
> -- Jamie

I don't think so. Here, we start with a 1 and shift it over into the
sign-bit. It now becomes the highest negative number. Now, we shift
it back exactly the same number of bits. See that the sign-bits are
__extended__! It now becomes -1.

Script started on Tue Jan 18 11:26:49 2000
# cat xxx.c
int main()
{
   int xxx = 1;

   printf("%08x (%d)\n", xxx, xxx);
   xxx <<= 31;
   printf("%08x (%d)\n", xxx, xxx);
   xxx >>= 31;
   printf("%08x (%d)\n", xxx, xxx);
   return 0;
}

# gcc -O2 -o xxx xxx.c
# ./xxx
00000001 (1)
80000000 (-2147483648)
ffffffff (-1)
# exit
exit

Script done on Tue Jan 18 11:27:15 2000

This is because 'C' treats shifts as arithmetic shifts, not logical
shifts. The code is (for Intel) sar and sal, not shr and shl. You
cannot reliably use shifts for ANDing operations if you are writing
in 'C'.

Cheers,
Dick Johnson

Penguin : Linux version 2.3.39 on an i686 machine (800.63 BogoMips).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:18 EST