linux/macros.h(new) and linux/list.h(mod) ...
This patch add a new linux/macros.h that is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain only min(), max() and abs().
The other change is to linux/list.h by adding two members list_first() and list_last().
- Davide
include/linux/list.h +4 -0
@@ -148,6 +148,10 @@*/ #define list_for_each (pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) + +#define list_first (head) (((head)->next != (head)) ? (head)->next: (struct list_head *) 0) + +#define list_last (head) (((head)->prev != (head)) ? (head)->prev: (struct list_head *) 0)#endif /* __KERNEL__ || _LVM_H_INCLUDE */
include/linux/macros.h +19 -0
@@ -0,0 +1,19 @@ +#ifndef _LINUX_MACROS_H +#define _LINUX_MACROS_H + + +#ifndef min +#define min (a, b) (((a) < (b)) ? (a): (b)) +#endif + +#ifndef max +#define max (a, b) (((a) > (b)) ? (a): (b)) +#endif + +#ifndef abs +#define abs (a) (((a) > 0) ? (a): -(a)) +#endif + + + +#endif
Quoted 3 lines · [email protected] said:
This patch add a new
linux/macros.hthat is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain onlymin(),max()andabs().
Consider min(x++,y++). Try:
#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; }) #define max(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_x:_y; })
--
dwmw2
Quoted 6 lines · On 05-Jul-2001 David Woodhouse wrote:
Quoted 3 lines · [email protected] said:
This patch add a new
linux/macros.hthat is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain onlymin(),max()andabs().
Quoted 6 lines
Consider
min(x++,y++). Try:#define
min(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; #})
#definemax(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_x:_y; #})
Yep, it's better.
- Davide
Doesn't it add more overhead? I think using inline functions are much better.
Yes you have to define it for different types (char, short, int, long,
signed/unsigned).
Quoted 4 lines
Yep, it's better.
- Davide
Quoted 2 lines · [email protected] said:
Doesn't it add more overhead? I think using inline functions are
much better.
Why should it add overhead? Even the most naïve compiler ought to generate the same code, surely? I must admit I haven't looked hard at the output - it didn't even occur to me that it might produce suboptimal code.
Quoted 2 lines
Yes you have to define it for different types (char, short, int,
long, signed/unsigned).
Unfortunately, this being C means that you can't call them all by the same name. If I have to use unsigned_long_max(x,y) I'd rather type it out myself :)
--
dwmw2
-> From David Woodhouse <[email protected]> :
Quoted 8 lines
Quoted 2 lines · [email protected] said:
Doesn't it add more overhead? I think using inline functions are
much better.Why should it add overhead? Even the most naïve compiler ought to generate the same code, surely? I must admit I haven't looked hard at the output - it didn't even occur to me that it might produce suboptimal code.
right, gcc -O2 does produce the same code (but -O does not).
Quoted 7 lines
Quoted 3 lines
Yes you have to define it for different types (char, short, int,
long, signed/unsigned).Unfortunately, this being C means that you can't call them all by the same name. If I have to use
unsigned_long_max(x,y)I'd rather type it out myself :)
Oops, I must be sleeping at that time :-)
Quoted 4 lines
--
dwmw2
Quoted 5 lines · On 05-Jul-2001 Hua Zhong wrote:
Doesn't it add more overhead? I think using inline functions are much better.
Yes you have to define it for different types (char, short, int, long,
signed/unsigned).
Yes it does.
Personally I know that min, max, etc... are macros and I never use unary operators inside.
Maybe a "unsafe" __max() and a "safe" max() could coexist.
- Davide
Quoted 6 lines · Davide Libenzi
Quoted 5 lines · On 05-Jul-2001 David Woodhouse wrote:
Quoted 3 lines · [email protected] said:
This patch add a new
linux/macros.hthat is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain onlymin(),max()andabs().
Quoted 8 lines
Quoted 6 lines
Consider
min(x++,y++). Try:#define
min(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; #})
#definemax(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_x:_y; #})Yep, it's better.
This program prints garbage:
#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; })
int main (void) {
int _x = 3, _y = 4;
printf("%i\n", min(_x, _y));
return 0;
}--
Daniel
Quoted 7 lines · [email protected] said:
This program prints garbage:
#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; }) int main (void) { int _x = 3, _y = 4; printf("%i\n", min(_x, _y)); return 0; }
Life's a bitch.
cf. get_user(__ret_gu, __val_gu); (on i386)
Time to invent a gcc extension which gives us unique names? :)
--
dwmw2
Quoted 11 lines · On 05-Jul-2001 David Woodhouse wrote:
Quoted 8 lines · [email protected] said:
This program prints garbage:
#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); #(_x>_y)?_y:_x; }) int main (void) { int _x = 3, _y = 4; printf("%i\n", min(_x, _y)); return 0; }
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
Something like ::(x) to move up one level the name resolution for example.
- Davide
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
#define min(a,b) __magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)
#define __magic_minfoo(A,B,C,D) \
{ typeof(A) C = (A) .... }Alan
#define min(a,b) __magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)
#define __magic_minfoo(A,B,C,D) \
({ typeof(A) C = (A); typeof(B) D = (B); C>D?D:C; })void main(void)
{
int __var11=5, __var211=7;
printf("min(%d,%d) = %d (should be 11: %d)\n", __var11, __var211, min(__var11, __var211), __LINE__);
}--
dwmw2
Quoted 9 lines · On 05-Jul-2001 Alan Cox wrote:
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ { typeof(A) C = (A) .... }
Anyway I think that :
int _a = 5;
for (;;) {
int _a = _a;
...
}must :
1) assign the upper level value of _a
or :
2) generate an compiler error
- Davide
Quoted 35 lines · you
Quoted 20 lines · Davide Libenzi
Quoted 9 lines · On 05-Jul-2001 Alan Cox wrote:
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ { typeof(A) C = (A) .... }Anyway I think that :
int _a = 5;
for (;;) { int _a = _a; ... }Quoted 7 lines
must :
1) assign the upper level value of _a
or :
2) generate an compiler error
Well, I happen to agree with you, but in this case, c's scope rules are stupidly broken, they are not going to change, and we have to live with it ;-)
--
Daniel
Em Fri, Jul 06, 2001 at 12:08:55AM +0100, David Woodhouse escreveu:
Quoted 6 lines
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ ({ typeof(A) C = (A); typeof(B) D = (B); C>D?D:C; })
Quoted 6 lines
void main(void)
{ int __var11=5, __var211=7; printf("min(%d,%d) = %d (should be 11: %d)\n", __var11, __var211, min(__var11, __var211), __LINE__); }
Have you looked at the preprocessor output?
[acme@brinquedo /tmp]$ gcc -E a.c -o - # or 'cpp < a.c'
# 1 "a.c"
void main(void)
{
int __var11=5, __var211=7;
printf("min(%d,%d) = %d (should be 11: %d)\n", __var11, __var211,+ ({ typeof( __var11 ) __var__LINE__ = ( __var11 ); typeof(__var211 ) __var2__LINE__ = ( __var211 ); __var__LINE__ >__var2__LINE__ ? __var2__LINE__ : __var__LINE__ ; }) , 11); }
I didn't found a way to generate unique variable names using __LINE__
- Arnaldo
Alan Cox wrote:-
Quoted 4 lines
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ { typeof(A) C = (A) .... }
No, that's buggy. You need an extra level of indirection to expand __LINE__. Arguments to ## are inserted in-place without expansion.
Neil.
Em Fri, Jul 06, 2001 at 06:38:04PM +0100, Neil Booth escreveu:
Quoted 9 lines
Alan Cox wrote:-
Quoted 4 lines
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ { typeof(A) C = (A) .... }No, that's buggy. You need an extra level of indirection to expand
__LINE__. Arguments to ## are inserted in-place without expansion.
yes, so lets try with another indirection and see if I'm missing something that you could clarify :)
[acme@brinquedo __attribute__]$ cat b.c
#define _min(a,b,line) __magic_minfoo(a,b, __var##line, __var2##line) #define min(a,b) _min(a,b,__LINE__)
#define __magic_minfoo(A,B,C,D) \
({ typeof(A) C = (A); typeof(B) D = (B); C>D?D:C; })void main(void)
{
int __var11=5, __var211=7;
printf("min(%d,%d) = %d (should be 11: %d)\n", __var11, __var211,
min(__var11, __var211), __LINE__);
}
[acme@brinquedo __attribute__]$ cpp < b.c
# 1 ""
void main(void)
{
int __var11=5, __var211=7;
printf("min(%d,%d) = %d (should be 11: %d)\n", __var11, __var211,
({ typeof( __var11 ) __var__LINE__ = ( __var11 );typeof( __var211 ) __var2__LINE__ = ( __var211 );__var__LINE__ > __var2__LINE__ ? __var2__LINE__ : __var__LINE__ ; }) , 12);
}
[acme@brinquedo __attribute__]$
- Arnaldo
Better, but throwing __FILE__ in there would be good too...
Come to think of it, tho, we have multiple files named the same thing in multiple places on the kernel tree... even __var##__LINE__##__FILE__ isn't _guaranteed_ to be unique.
Matt
Quoted 18 lines · Alan Cox
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
#define
min(a,b)__magic_minfoo(a,b, __var##__LINE__, __var2##__LINE__)#define __magic_minfoo(A,B,C,D) \ { typeof(A) C = (A) .... }Alan
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 6 lines
Matthew Dharm Home: [email protected] Maintainer, Linux USB Mass Storage Driver Ye gods! I have feet??! -- Dust Puppy User Friendly, 12/4/1997
Quoted 1 line
Better, but throwing
__FILE__in there would be good too...
Totally inappropriate. These are not global variables and a filename is not legal variable namespace anyway
Quoted 13 lines · On 20010706 Davide Libenzi wrote:
Quoted 11 lines · On 05-Jul-2001 David Woodhouse wrote:
Quoted 8 lines · [email protected] said:
This program prints garbage:
#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); #(_x>_y)?_y:_x; }) int main (void) { int _x = 3, _y = 4; printf("%i\n", min(_x, _y)); return 0; }
Quoted 7 lines
Quoted 4 lines
Life's a bitch.
cf.get_user(__ret_gu, __val_gu); (on i386)Time to invent a gcc extension which gives us unique names? :)
Something like ::(x) to move up one level the name resolution for example.
Tell gcc people to support <? and >? in C besides C++.
Signature · 4 lines
J.A. Magallon # Let the source be with you... mailto:[email protected] Mandrake Linux release 8.1 (Cooker) for i586 Linux werewolf 2.4.6-ac1 #2 SMP Thu Jul 5 01:15:49 CEST 2001 i686
Quoted 8 lines · On 20010705 Davide Libenzi wrote:
Quoted 6 lines · On 05-Jul-2001 David Woodhouse wrote:
Quoted 3 lines · [email protected] said:
This patch add a new
linux/macros.hthat is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain onlymin(),max()andabs().
Quoted 8 lines
Quoted 6 lines
Consider
min(x++,y++). Try:#define
min(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; #})
#definemax(x,y)({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_x:_y; #})Yep, it's better.
And there could be others also usefull:
#define ztst(x,y) (x ?: y) // x' if that is nonzero; otherwise, of y'
If g++ extensions worked in plain C, you just could write:
#define min(x,y) (x <? y)
#define max(x,y) (x >? y)
Signature · 4 lines
J.A. Magallon # Let the source be with you... mailto:[email protected] Mandrake Linux release 8.1 (Cooker) for i586 Linux werewolf 2.4.6-ac1 #2 SMP Thu Jul 5 01:15:49 CEST 2001 i686
Quoted 3 lines · Davide Libenzi
This patch add a new
linux/macros.hthat is supposed to host utility macros that otherwise developers are forced to define in their files. This version contain onlymin(),max()andabs().
It's a good old tradition to put macros in uppercase letters. This would have avoided one fatal error in your patch, the conflict with the gcc built-in
int abs(int);
which has it's prototype in include/linux/kernel.h. There's places which depend on this and would break with your macro.
Also, unless you have more macros in mind, it may make sense to just place MIN, MAX in kernel.h and of course to remove similar macro definitions throughout the kernel and replace them by the commonly defined ones.
--Kai