2001-07-05 20:58:44

by Davide Libenzi

[permalink] [raw]
Subject: 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


Attachments:
misc.diff (1.05 kB)
misc.diff

2001-07-05 21:31:58

by David Woodhouse

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


[email protected] said:
> 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().

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


2001-07-05 21:42:21

by Davide Libenzi

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


On 05-Jul-2001 David Woodhouse wrote:
>
> [email protected] said:
>> 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().
>
> 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;
>#})

Yep, it's better.




- Davide

2001-07-05 21:54:44

by Hua Zhong

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


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).

> Yep, it's better.
>
>
> - Davide


2001-07-05 21:59:54

by David Woodhouse

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


[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.

> 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


2001-07-05 22:03:34

by Davide Libenzi

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


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

2001-07-05 22:10:35

by J.A. Magallon

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


On 20010705 Davide Libenzi wrote:
>
>On 05-Jul-2001 David Woodhouse wrote:
>>
>> [email protected] said:
>>> 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().
>>
>> 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;
>>#})
>
>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)

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

2001-07-05 22:10:55

by Kai Germaschewski

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

On Thu, 5 Jul 2001, Davide Libenzi wrote:

> 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().

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

2001-07-05 22:21:17

by Hua Zhong

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

-> From David Woodhouse <[email protected]> :
>
> [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).

>
> > 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 :-)

> --
> dwmw2
>
>


2001-07-05 22:30:39

by Daniel Phillips

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

On Thursday 05 July 2001 23:45, Davide Libenzi wrote:
> On 05-Jul-2001 David Woodhouse wrote:
> > [email protected] said:
> >> 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().
> >
> > 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; #})
>
> 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

2001-07-05 22:43:29

by David Woodhouse

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


[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


2001-07-05 22:50:30

by Davide Libenzi

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


On 05-Jul-2001 David Woodhouse wrote:
>
> [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? :)

Something like ::(x) to move up one level the name resolution for example.



- Davide

2001-07-05 22:58:41

by Alan

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

> 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

2001-07-05 23:07:01

by Matthew Dharm

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

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

On Thu, Jul 05, 2001 at 11:57:11PM +0100, Alan Cox wrote:
> > 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/

--
Matthew Dharm Home: [email protected]
Maintainer, Linux USB Mass Storage Driver

Ye gods! I have feet??!
-- Dust Puppy
User Friendly, 12/4/1997


Attachments:
(No filename) (1.03 kB)
(No filename) (232.00 B)
Download all attachments

2001-07-05 23:09:01

by Alan

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

> 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

2001-07-05 23:10:32

by David Woodhouse

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


#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


2001-07-05 23:18:51

by Davide Libenzi

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


On 05-Jul-2001 Alan Cox wrote:
>> 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

2001-07-05 23:23:33

by J.A. Magallon

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...


On 20010706 Davide Libenzi wrote:
>
>On 05-Jul-2001 David Woodhouse wrote:
>>
>> [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? :)
>
>Something like ::(x) to move up one level the name resolution for example.
>

Tell gcc people to support <? and >? in C besides C++.

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

2001-07-05 23:50:49

by Daniel Phillips

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

On Friday 06 July 2001 01:49, you wrote:
> On Friday 06 July 2001 01:21, Davide Libenzi wrote:
> > On 05-Jul-2001 Alan Cox wrote:
> > >> 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
>
> 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

2001-07-06 01:52:18

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

Em Fri, Jul 06, 2001 at 12:08:55AM +0100, David Woodhouse escreveu:
>
> #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__);
> }

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

2001-07-06 17:40:20

by Neil Booth

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

Alan Cox wrote:-

> #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.

2001-07-06 22:02:35

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: linux/macros.h(new) and linux/list.h(mod) ...

Em Fri, Jul 06, 2001 at 06:38:04PM +0100, Neil Booth escreveu:
> Alan Cox wrote:-
>
> > #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