lkml.org 
[lkml]   [2001]   [Sep]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [IDEA+RFC] Possible solution for min()/max() war
From
Date
>>>>> 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/

\
 
 \ /
  Last update: 2005-03-22 13:02    [W:0.305 / U:0.144 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site