Re: [IDEA+RFC] Possible solution for min()/max() war

Bill Pringlemeir (bpringle@sympatico.ca)
07 Sep 2001 10:39:57 -0400


>>>>> Peter T Breuer <ptb@it.uc3m.es> writes:

> If you are interested, the last version I had is the
> following. The compile_time_assert is linus' idea. We had an
> illegal assembler statement there originally, containing the line
> number and the error statement. One or the other will do until gcc
> gets the __builtin_ct_assert() function.

#define compile_time_assert(x) \
do { switch (0) { case 0: case (x) != 0: ; } } while (0)

#define __MIN(x,y) ({\
typeof(x) _x = x; \
typeof(y) _y = y; \
_x < _y ? _x : _y ; \
})
#define MIN(x,y) ({\
const typeof(x) _x = ~(typeof(x))0; \
const typeof(y) _y = ~(typeof(y))0; \
compile_time_assert(sizeof(_x) == sizeof(_y));\
compile_time_assert( (_x > (typeof(x))0 && _y > (typeof(y))0) \
|| (_x < (typeof(x))0 && _y < (typeof(y))0)); \
__MIN(x,y); \
})

As Horst von Brand noted, most modern machines use 2's complement
arithmetic. AFAIK, all the Linux targets use 2's complement. The use
of ones complement, probably pre-dates MMUs. At any rate, I think
that this might be a little clearer as sign, not complement is what is
being checked.

#define MIN(x,y) ({\
const typeof(x) _x = 0; \
const typeof(y) _y = 0; \
compile_time_assert(sizeof(_x) == sizeof(_y));\
compile_time_assert( (_x - 1 > 0 && _y - 1 > 0) \
|| (_x - 1 < 0 && _y - 1 < 0)); \
__MIN(x,y); \
})

This should prevent all cases where the __MIN(x,y) macro can screw up
due to sign issues (on that machine). If you do this, the `sizeof'
check isn't needed. A MIN(int, long) etc should probably be ok. The
only caveats are the promotion in the __MIN itself create a sign
mismatch.

However, if the `sizeof' check remains, then you don't have to worry
about this and both versions are equivalent. Some other things to
worry about is what if the type is already const? Maybe that works...
What if you try `MIN(x,_x);'. I think that this is something that
David took care of in the "3 arg min".

regards,
Bill Pringlemeir.

-
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/