Messages in this thread |  | | Subject | Re: [IDEA+RFC] Possible solution for min()/max() war | From | Bill Pringlemeir <> | Date | 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/
|  |