Messages in this thread |  | | Subject | Re: [IDEA+RFC] Possible solution for min()/max() war | From | Bill Pringlemeir <> | Date | 06 Sep 2001 20:52:27 -0400 |
| |
>>>>> Peter T Breuer <ptb@it.uc3m.es> writes:
> To give you all something definite to look at, here's some test > code:
> // standard good 'ol faithful version > #define __MIN(x,y) ({\ > typeof(x) _x = x; \ > typeof(y) _y = y; \ > _x < _y ? _x : _y ; \ > })
> // possible implemetation with type sanity checks - alter to taste > #define MIN(x,y) ({\ > const typeof(x) _x = ~(typeof(x))0; \ > const typeof(y) _y = ~(typeof(y))0; \ > void MIN_BUG(); \ > if (sizeof(_x) != sizeof(_y)) \ > MIN_BUG(); \ > if ((_x > 0 && _y < 0) || (_x < 0 && _y > 0)) \ > MIN_BUG(); \ > __MIN(x,y); \ > })
[snip]
Sorry, I have been away for a while. I think that I was talking about a similar approach when Linus was away and David introduced the 3 arg min/max. I just went through 1800 LKML emails and I am not quite clear what happened. I have put my code that I posted earlier at the end of this email. This was the result of someone's `fanciful comment' `what if gcc could handle "if(strcmp(typeof(a),typeof(b))!=0)"'.
So here is the important part. The code Peter has introduced a cast in the lines "const typeof(x) _x = ~(typeof(x))0;" etc. I think that the approach of declaring a variable of the type and initializing to zero and then comparing "x - 1" _might_ be better.
The version of min() at the end calls the following an error, were Peter's does not [after removing the sizeof() restriction].
unsigned char Cx = 1; unsigned int Ix = 1; unsigned long Lx = 1; Ix = min(Cx,Ix); Lx = min(Cx,Lx);
Here the unsigned char is being promoted to int as discussed before. I think that this is `more faithful' as what we are try to achieve is to check the sign that will be used in the min comparison; almost like applying a proper warned signed selectively to the min/max macros.
Otherwise, I think we have independently came up with the same thing and the `error' throwing can of course be changed to whatever.
fwiw, Bill Pringlemeir.
[start code]
#define bug_paste_chain(a,b) a##b #define bug_paste(a) bug_paste_chain(BUG_AT_LINE_,a) #define min(x,y) \ \ ({extern void bug_paste(__LINE__) (void); \ typeof(x) _x = 0; typeof(y) _y = 0; \ if ((_x-1>0 && _y-1<0) || (_x-1<0 && _y-1>0)) \ bug_paste(__LINE__)(); \ _x = (x), _y = (y); (_x>_y)?_y:_x; \ })
#include <stdio.h> int main(int argc, char *argv[]) { signed char cx = 1, cy = 2; signed short sx = 1, sy = 2; signed int ix = 1, iy = 2; signed long lx = 1, ly = 2; unsigned char Cx = 1, Cy = 2; unsigned short Sx = 1, Sy = 2; unsigned int Ix = 1, Iy = 2; unsigned long Lx = 1, Ly = 2;
cx = min(cx,cy); Cx = min(Cy,Cx); sx = min(sx,sy); Sx = min(Sx,Sy); ix = min(iy,ix); Ix = min(Iy,Ix); lx = min(ly,ly); Lx = min(Lx,Ly);
/* No warning. */ /* Lx = (typeof(Lx))min(Lx,&Ly); */
printf("%d %d %hd %hd %d %d %ld %ld\n", cx, Cx, sx,Sx,ix,Ix,lx,Lx);
cx = -1; Cx = 0; cx = min(cx,cy); sx = min(cx,sy); ix = min(cx,ix); lx = min(cx,ly); Cx = min(Cx,Cx); Sx = min(Cx,Sy); Ix = min(Ly,Ix); Lx = min(Ix,Ly);
/* correctly gives warning! */ /* Ix = min(Cy,Ix); Lx = min(Cx,Ly); */
printf("%d %d %hd %hd %d %d %ld %ld\n", cx, Cx, sx,Sx,ix,Ix,lx,Lx);
min((unsigned)ix,sizeof(ix)); /* BUG? printf ("%d\n", min(Iy, 10)); */ printf ("%d\n", min(cx, 20));
printf("min(3,4,5) %d\n", min(min(5,4),3)); return 0; } /* gcc -Wall -O2 -o test test.c */
[end code]
- 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/
|  |