Re: [BUG] Bad #define, nonportable C, missing {}

From: Jan Hudec (bulb@ucw.cz)
Date: Wed Nov 21 2001 - 08:37:38 EST


> > *a++ = byte_rev[*a]
> It looks perferctly okay to me. Anyway, whenever would you listen to a
> C++ book talking about good C coding :p

AFAIK the ANSI C specification explicitely claims, that it's not defined.
The trick is, that the specification explicitly allows the compiler to
choose wether it does the inc/dec right after/before the fetch, or at the
begin/end of evaluation. Thus the second reference to a might return the
original or incremented value at compiler's will.

> Go read up on C operator precedence. Unary ++ comes before %, so if we
> rewrite the #define to make it more "readable" it would be #define
> MODINC(x,y) (x = (x+1) % y)

*NO*
MODINC(x,y) (x = (x+1) % y)
is correct and beaves as expected. Unfortunately:
MODINC(x,y) (x = x++ % y)
is a nonsence, because the evaluation is something like this
x++ returns x
x++ % y returns x % y
x is assigned the result and it's incremented IN UNDEFINED ORDER!!!
AFAIK the ANSI C spec explicitly undefines the order.

> > *a++ = byte_rev[*a];
> C std says *always* evaluate from right to left for = operators, so this
> will always make perfect sense.
Yes, this should make perfect sense, but I fear the spec talks about
operand used twice, once with side-efect generaly. So to be ANSI C
correct, it's not good.

-------------------------------------------------------------------------------
                                                  - Jan Hudec `Bulb' <bulb@ucw.cz>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Nov 23 2001 - 21:00:27 EST