* asm/unistd.h
@ 2001-04-05 12:58 Sardañons, Eliel
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Sardañons, Eliel @ 2001-04-05 12:58 UTC (permalink / raw)
To: 'linux-kernel@vger.kernel.org'
I'm taking a look at the linux code and I don't understand how do you
programm...mmm (?) may be i'm a stupid why in include/asm/unistd.h in some
macros you use this:
do {
...
} while (0)
Thanks in advance.
Eliel C. Sardanons
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 12:58 asm/unistd.h Sardañons, Eliel
@ 2001-04-05 13:06 ` Bart Trojanowski
2001-04-05 13:12 ` asm/unistd.h Tim Waugh
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
2001-04-05 13:07 ` asm/unistd.h David S. Miller
2001-04-05 13:13 ` asm/unistd.h Ben Collins
2 siblings, 2 replies; 13+ messages in thread
From: Bart Trojanowski @ 2001-04-05 13:06 UTC (permalink / raw)
To: Sardañons, Eliel; +Cc: 'linux-kernel@vger.kernel.org'
On Thu, 5 Apr 2001, Sardañons, Eliel wrote:
> I'm taking a look at the linux code and I don't understand how do you
> programm...mmm (?) may be i'm a stupid why in include/asm/unistd.h in some
> macros you use this:
>
> do {
> ...
> } while (0)
This is a very useful trick.
If you define a macro such as:
#define foo(x) do_one(x); do_two(x); do_three(x)
you may later be compelled to call it in an if statement:
if(condition)
foo(something);
note that it would not do what you want as it will only execute do_one(x)
conditionally but do_two(x) and do_three(x) would always be done.
However a do{ ... } while(0) is a nice convenient block which is
guaranteed to execute once. The compiler (with a -O flag) will not
generate any extra code for the do{}while(0) so its just a macro building
aid.
So you ask: "why not just use a { ... } to define a macro". I don't
remember the case for this but I know it's there. It has to do with a
complicated if/else structure where a simple {} breaks.
Cheers,
Bart.
--
WebSig: http://www.jukie.net/~bart/sig/
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
@ 2001-04-05 13:12 ` Tim Waugh
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
1 sibling, 0 replies; 13+ messages in thread
From: Tim Waugh @ 2001-04-05 13:12 UTC (permalink / raw)
To: Bart Trojanowski
Cc: Sardañons, Eliel, 'linux-kernel@vger.kernel.org'
[-- Attachment #1: Type: text/plain, Size: 338 bytes --]
On Thu, Apr 05, 2001 at 09:06:20AM -0400, Bart Trojanowski wrote:
> So you ask: "why not just use a { ... } to define a macro". I don't
> remember the case for this but I know it's there. It has to do with a
> complicated if/else structure where a simple {} breaks.
It's for eating the semi-colon after the macro invocation.
Tim.
*/
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
2001-04-05 13:12 ` asm/unistd.h Tim Waugh
@ 2001-04-05 14:26 ` Joseph Carter
2001-04-05 14:35 ` asm/unistd.h Bart Trojanowski
` (2 more replies)
1 sibling, 3 replies; 13+ messages in thread
From: Joseph Carter @ 2001-04-05 14:26 UTC (permalink / raw)
To: Bart Trojanowski; +Cc: 'linux-kernel@vger.kernel.org'
[-- Attachment #1: Type: text/plain, Size: 650 bytes --]
On Thu, Apr 05, 2001 at 09:06:20AM -0400, Bart Trojanowski wrote:
> So you ask: "why not just use a { ... } to define a macro". I don't
> remember the case for this but I know it's there. It has to do with a
> complicated if/else structure where a simple {} breaks.
This doesn't follow in my mind. I can't think of a case where a { ... }
would fail, but a do { ... } while (0) would succeed. The former would
also save a few keystrokes.
--
Joseph Carter <knghtbrd@debian.org> Free software developer
// Minor lesson: don't fuck about with something you don't fully understand
-- the dosdoom source code
[-- Attachment #2: Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
@ 2001-04-05 14:35 ` Bart Trojanowski
2001-04-05 14:35 ` asm/unistd.h Stephen Thomas
2001-04-05 14:45 ` asm/unistd.h Andreas Schwab
2 siblings, 0 replies; 13+ messages in thread
From: Bart Trojanowski @ 2001-04-05 14:35 UTC (permalink / raw)
To: Joseph Carter; +Cc: 'linux-kernel@vger.kernel.org'
On Thu, 5 Apr 2001, Joseph Carter wrote:
> On Thu, Apr 05, 2001 at 09:06:20AM -0400, Bart Trojanowski wrote:
> > So you ask: "why not just use a { ... } to define a macro". I don't
> > remember the case for this but I know it's there. It has to do with a
> > complicated if/else structure where a simple {} breaks.
>
> This doesn't follow in my mind. I can't think of a case where a { ... }
> would fail, but a do { ... } while (0) would succeed. The former would
> also save a few keystrokes.
Tim Waugh already stated this one:
#define foo(x) { do_something(x) }
if( condition )
foo(x);
else
foo(y);
would produce
if( condition )
{ do_something(x) };
else
{ do_something(y) };
note the semi-colon at the end of {.*}.
This is bad because it forces you to use the foo macro knowing it's a
macro and not a function.
So you say I will use it like this:
if( condition )
foo(x)
else
foo(y)
That's just great for this case, but now imagine that on some other
architecture doing foo(x) takes many many lines with recursion and all.
You don't want that to be in a macro so you make a function. And you get
many many compiler errors on thsi new platform.
Cheers,
Bart.
--
WebSig: http://www.jukie.net/~bart/sig/
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
2001-04-05 14:35 ` asm/unistd.h Bart Trojanowski
@ 2001-04-05 14:35 ` Stephen Thomas
2001-04-05 14:45 ` asm/unistd.h Andreas Schwab
2 siblings, 0 replies; 13+ messages in thread
From: Stephen Thomas @ 2001-04-05 14:35 UTC (permalink / raw)
To: Joseph Carter; +Cc: Bart Trojanowski, 'linux-kernel@vger.kernel.org'
Joseph Carter wrote:
> This doesn't follow in my mind. I can't think of a case where a { ... }
> would fail, but a do { ... } while (0) would succeed. The former would
> also save a few keystrokes.
#define FOO(x) { wibble(x); wobble((x)+1);}
if (something)
FOO(23);
else /* Compile goes crump here. */
another_thing();
Stephen Thomas
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
2001-04-05 14:35 ` asm/unistd.h Bart Trojanowski
2001-04-05 14:35 ` asm/unistd.h Stephen Thomas
@ 2001-04-05 14:45 ` Andreas Schwab
2001-04-05 17:38 ` asm/unistd.h J . A . Magallon
2 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2001-04-05 14:45 UTC (permalink / raw)
To: Joseph Carter; +Cc: Bart Trojanowski, 'linux-kernel@vger.kernel.org'
Joseph Carter <knghtbrd@debian.org> writes:
|> On Thu, Apr 05, 2001 at 09:06:20AM -0400, Bart Trojanowski wrote:
|> > So you ask: "why not just use a { ... } to define a macro". I don't
|> > remember the case for this but I know it's there. It has to do with a
|> > complicated if/else structure where a simple {} breaks.
|>
|> This doesn't follow in my mind. I can't think of a case where a { ... }
|> would fail, but a do { ... } while (0) would succeed. The former would
|> also save a few keystrokes.
Try this and watch your compiler complaining:
#define foo() { }
#define bar() do { } while (0)
void mumble ()
{
if (1) foo(); else bar();
if (2) bar(); else foo();
}
Andreas.
--
Andreas Schwab "And now for something
SuSE Labs completely different."
Andreas.Schwab@suse.de
SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 14:45 ` asm/unistd.h Andreas Schwab
@ 2001-04-05 17:38 ` J . A . Magallon
0 siblings, 0 replies; 13+ messages in thread
From: J . A . Magallon @ 2001-04-05 17:38 UTC (permalink / raw)
To: Andreas Schwab
Cc: Joseph Carter, Bart Trojanowski,
'linux-kernel @ vger . kernel . org'
On 04.05 Andreas Schwab wrote:
>
> Try this and watch your compiler complaining:
>
> #define foo() { }
> #define bar() do { } while (0)
> void mumble ()
> {
> if (1) foo(); else bar();
> if (2) bar(); else foo();
> }
>
Perhaps it is time to USE gcc, yet the kernel can be built only with gcc.
IE, use statement expressions.
Try this:
#define foo() ({ })
#define bar() do { } while (0)
void mumble ()
{
if (1) foo(); else bar();
if (2) bar(); else foo();
}
and see you compiler shutup.
You can even declare vars inside the ({ ... }) block,
so all the
#define bar(x) do { use_1(x); use_2(x); } while (0)
could be written like:
#define bar(x) ({ use_1(x); use_2(x); })
Even you can use <typeof>:
#define swap(a,b) \
({ typeof(a) tmp = a; \
a = b; \
b = tmp; \
})
int main()
{
int a,b;
double c,d;
swap(a,b);
swap(c,d);
}
Its correct in egcs-1.1.2 and up, so it is safe for use in kernel 2.4.
Do not know if previuous gcc eats it up.
--
J.A. Magallon # Let the source
mailto:jamagallon@able.es # be with you, Luke...
Linux werewolf 2.4.3-ac3 #1 SMP Thu Apr 5 00:28:45 CEST 2001 i686
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: asm/unistd.h
2001-04-05 12:58 asm/unistd.h Sardañons, Eliel
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
@ 2001-04-05 13:07 ` David S. Miller
2001-04-05 13:13 ` asm/unistd.h Ben Collins
2 siblings, 0 replies; 13+ messages in thread
From: David S. Miller @ 2001-04-05 13:07 UTC (permalink / raw)
To: =?ISO-8859-1?Q?Sarda=F1ons, ?= Eliel
Cc: 'linux-kernel@vger.kernel.org'
Sardañons@pizda.ninka.net, Eliel writes:
> I'm taking a look at the linux code and I don't understand how do you
> programm...mmm (?) may be i'm a stupid why in include/asm/unistd.h in some
> macros you use this:
Two reasons:
1) Empty statements give a warning from the compiler so
this is why you see "#define FOO do { } while(0)"
2) It gives you a basic block in which to declare local
variables.
Later,
David S. Miller
davem@redhat.com
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: asm/unistd.h
2001-04-05 12:58 asm/unistd.h Sardañons, Eliel
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
2001-04-05 13:07 ` asm/unistd.h David S. Miller
@ 2001-04-05 13:13 ` Ben Collins
2 siblings, 0 replies; 13+ messages in thread
From: Ben Collins @ 2001-04-05 13:13 UTC (permalink / raw)
To: Sarda?ons, Eliel; +Cc: 'linux-kernel@vger.kernel.org'
On Thu, Apr 05, 2001 at 09:58:43AM -0300, Sarda?ons, Eliel wrote:
> I'm taking a look at the linux code and I don't understand how do you
> programm...mmm (?) may be i'm a stupid why in include/asm/unistd.h in some
> macros you use this:
>
> do {
> ...
> } while (0)
Imagine a macro of several lines of code like:
#define FOO(x) \
printf("arg is %s\n", x); \
do_something_useful(x);
Now imagine using it like:
if (blah == 2)
FOO(blah);
This interprets to
if (blah == 2)
printf("arg is %s\n", blah);
do_something_useful(blah);;
As you can see, the "if" then only encompasses the printf, and the
do_something_useful() call is unconditional (not within the scope of the
if), like you wanted it.
So, by using a block like do{...}while(0), you would get this:
if (blah == 2)
do {
printf("arg is %s\n", blah);
do_something_useful(blah);
} while (0);
Which is exactly what you want.
--
-----------=======-=-======-=========-----------=====------------=-=------
/ Ben Collins -- ...on that fantastic voyage... -- Debian GNU/Linux \
` bcollins@debian.org -- bcollins@openldap.org -- bcollins@linux.com '
`---=========------=======-------------=-=-----=-===-======-------=--=---'
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: asm/unistd.h
@ 2001-04-05 15:23 Steve Grubb
2001-04-05 15:41 ` asm/unistd.h Bart Trojanowski
2001-04-05 15:45 ` asm/unistd.h David S. Miller
0 siblings, 2 replies; 13+ messages in thread
From: Steve Grubb @ 2001-04-05 15:23 UTC (permalink / raw)
To: linux-kernel
It would seem to me that after hearing how the macros are used in practice,
wouldn't turning them into inline functions be an improvement? This is
something gcc supports, it accomplishes the same thing, and has the added
advantage of type checking.
http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC92
Or perhaps type checking macro arguments would be another fertile area for
the Stanford Checker...
Cheers,
Steve Grubb
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: asm/unistd.h
2001-04-05 15:23 asm/unistd.h Steve Grubb
@ 2001-04-05 15:41 ` Bart Trojanowski
2001-04-05 15:45 ` asm/unistd.h David S. Miller
1 sibling, 0 replies; 13+ messages in thread
From: Bart Trojanowski @ 2001-04-05 15:41 UTC (permalink / raw)
To: Steve Grubb; +Cc: linux-kernel
On Thu, 5 Apr 2001, Steve Grubb wrote:
> It would seem to me that after hearing how the macros are used in practice,
> wouldn't turning them into inline functions be an improvement? This is
> something gcc supports, it accomplishes the same thing, and has the added
> advantage of type checking.
> http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC92
>
> Or perhaps type checking macro arguments would be another fertile area for
> the Stanford Checker...
There are benefits to macros too. One that I like for debuggin is that
the C parser will unravel a macro within the context of the execution:
#ifdef DEBUG
#define KMALLOC(x,y) \
printk(__FILE__ ":%d: kmalloc(%d,%d")\n", __LINE__,x,y); \
kmalloc(x,y);
#else
#define KMALLOC(x,y) \
kmalloc(x,y);
#endif
I think the benefit of a macro here is quite visible... you cannot do this
with an inline.
You may also look at some better reasons:
http://www.uwsg.iu.edu/hypermail/linux/kernel/9810.3/0323.html
[btw I found this by looking for 'macros vs inline' on google/linux]
Bart.
--
WebSig: http://www.jukie.net/~bart/sig/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: asm/unistd.h
2001-04-05 15:23 asm/unistd.h Steve Grubb
2001-04-05 15:41 ` asm/unistd.h Bart Trojanowski
@ 2001-04-05 15:45 ` David S. Miller
1 sibling, 0 replies; 13+ messages in thread
From: David S. Miller @ 2001-04-05 15:45 UTC (permalink / raw)
To: Steve Grubb; +Cc: linux-kernel
Steve Grubb writes:
> It would seem to me that after hearing how the macros are used in practice,
> wouldn't turning them into inline functions be an improvement? This is
> something gcc supports, it accomplishes the same thing, and has the added
> advantage of type checking.
> http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC92
Two reasons:
1) Sometimes I don't want any type checking because it would create
the necessity of adding a new include to a file --> a circular
dependency to resolve. Macros hide the types except in the
cases where they are actually invoked :-)
2) Historically GCC was very bad with code generation with inline
functions, so at that time the GCC manual statement "inline
functions are just like a macro" was technically false :-)
Yes, I know this is much different in today's gcc tree, but
there hasn't been a gcc release in over 2 years so...
Later,
David S. Miller
davem@redhat.com
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2001-04-05 17:39 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-04-05 12:58 asm/unistd.h Sardañons, Eliel
2001-04-05 13:06 ` asm/unistd.h Bart Trojanowski
2001-04-05 13:12 ` asm/unistd.h Tim Waugh
2001-04-05 14:26 ` asm/unistd.h Joseph Carter
2001-04-05 14:35 ` asm/unistd.h Bart Trojanowski
2001-04-05 14:35 ` asm/unistd.h Stephen Thomas
2001-04-05 14:45 ` asm/unistd.h Andreas Schwab
2001-04-05 17:38 ` asm/unistd.h J . A . Magallon
2001-04-05 13:07 ` asm/unistd.h David S. Miller
2001-04-05 13:13 ` asm/unistd.h Ben Collins
-- strict thread matches above, loose matches on Subject: below --
2001-04-05 15:23 asm/unistd.h Steve Grubb
2001-04-05 15:41 ` asm/unistd.h Bart Trojanowski
2001-04-05 15:45 ` asm/unistd.h David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox