Re: Recent change in tcp_output.c is surely wrong

From: Rogier Wolff (R.E.Wolff@BitWizard.nl)
Date: Tue Jan 18 2000 - 04:53:42 EST


Andi Kleen wrote:

> On Tue, Jan 18, 2000 at 10:19:20AM +0100, Rogier Wolff wrote:
> > var = CLEAR_BIT_31(var);
> [...]
> And who maintains the macros?

The macro is marked clearly that it clears bit 31, (in the name) and
it is clearly marked with a comment WHY it is done this way.

> > everybody knows what you are doing without having to ask you....
>
> I think "everybody" knew that, the original poster just pointed out that
> the shift trick exploited undefined behaviour in ANSI-C, which is rather
> irrelevant because the Linux kernel is not writen in ANSI-C.

On the other hand, having thousands "silent departures from ANSI-C"
scattered through the kernel is not a good idea. I'm fine with having
a few __asm__ thingies that generate errors while compiling/linking.

Someone is eventually going to have to port Linux to an architecture
that doesn't have a gcc port yet.

Even if the original "complainer" was talking about departure from
ansi-C, the argument about readability still stands. Everybody knows
the construct &= 0xff to clear bits 8-31. This shift one is new
in that you have to look at it for a while.

Oh, by the way, ANSI defines the behaviour as undefined, as a compiler
is allowed to recognize that (var <<1) >> 1 evaluates to "var" if done
with arbitrary precision.

for example

        array [index>>4].firstbyte = 0;

could evaluate (the element size of array happens to be 16 bytes!)

        * (char *)array + (index & ~0xf) = 0;

See, the compiler recognized that two shifts over the same width are
the same. So recognizing this, is valid. So, if you depend on the
compiler trying to store the 33 bit result of your (var << 1) in a
register, you're going to get a surprise one day when it no longer
works.

Even if "ansi" says it is undefined doesn't mean that compilers may
not follow ansi. GCC-3.5 is fully free to implement the optimization,
BECAUSE ansi says it's undefined. Scattering gcc-dependencies all over
the place makes things hard once the compiler starts getting upgraded,
as with "egcs". See how painful that was. You always end up silently
using "features" of the compiler. Simply because programmers aren't
perfect. So a forgotten "this asm statement modifies memory" will not
get noticed until a compiler uses that knowledge to reorder things
so that they no longer work.

I'd prefer having the kernel in such a state that we try to minimize
such "surprises" for the future, by marking the spots where we realize
that we're mis-using a compiler restriction....

                Roger.

-- 
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
 "I didn't say it was your fault. I said I was going to blame it on you."

- 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:17 EST