For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > April 2007 > Werid <sys/queue.h> - it has useless do{} while(0)









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Werid <sys/queue.h> - it has useless do{} while(0)
djhong@gmail.com

2007-04-26, 7:05 pm

(Since queue.h is not a part of standard C, I'd lke to ask here)

For example, BSD implementation of sys/queue.h has following weird
macros:
I can't understand why "do{}while(0)" is used... Removing
"do{}while(0)" from these macros should be ok. Right?


#define SLIST_INIT(head) do { \
SLIST_FIRST((head)) = NULL; \
} while (0)

#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
SLIST_NEXT((slistelm), field) = (elm); \
} while (0)

#define SLIST_INSERT_HEAD(head, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
SLIST_FIRST((head)) = (elm); \
} while (0)

#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)

Eric Sosman

2007-04-26, 7:05 pm

djhong@gmail.com wrote On 04/26/07 13:47,:
> (Since queue.h is not a part of standard C, I'd lke to ask here)
>
> For example, BSD implementation of sys/queue.h has following weird
> macros:
> I can't understand why "do{}while(0)" is used... Removing
> "do{}while(0)" from these macros should be ok. Right?
>
>
> #define SLIST_INIT(head) do { \
> SLIST_FIRST((head)) = NULL; \
> } while (0)
>
> #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
> SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
> SLIST_NEXT((slistelm), field) = (elm); \
> } while (0)
>
> #define SLIST_INSERT_HEAD(head, elm, field) do { \
> SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
> SLIST_FIRST((head)) = (elm); \
> } while (0)
>
> #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)


(You seem to be missing some backslashes.)

No reason I can see for do{}while(0) on the first
one, but for the next two it makes sense. Maybe the
first has do{}while(0) just for consistency's sake, or
maybe an earlier version of the first macro had more
than one statement.

The reason for the do{}while(0) dodge in multi-
statement macro expansions is to make them work right
in contexts where just one statement is allowed. For
example, try this simple macro:

#define MESSAGE(msg) { \
fputs (msg, stdout);
fputs (msg, stderr);
}

Easy enough, right? MESSAGE("Hello, world!\n") writes
the message to two output streams. But let's try it
in this context:

if (firstGreetingOfTheDay)
MESSAGE("Hello, world!\n");
else
MESSAGE("Hi again.\n");

(If you don't see the problem, feed it to a compiler
and see what it says.)

Now, you could "fix" this with documentation: "When
you use the MESSAGE macro, never put a semicolon at
the end." But that's not a really wonderful solution
because it requires the programmer to be aware that this
"function-like macro" is really a macro and not an actual
function, and requires that it be coded with a different
style than pretty much everything else. (And it will
probably raise merry Hell with automatic code formatters,
too.) The do{}while(0) dodge turns the macro expansion
into a single semicolon-terminated statement, and the
programmer's life gets simpler.

--
Eric.Sosman@sun.com
Eric Sosman

2007-04-26, 7:05 pm

Eric Sosman wrote On 04/26/07 14:34,:
> djhong@gmail.com wrote On 04/26/07 13:47,:
> [...]
>
> (You seem to be missing some backslashes.)


Woops! You're not missing backslashes; I was
using too narrow a window. Sorry about that.

--
Eric.Sosman@sun.com
karl malbrain

2007-04-26, 7:05 pm

"Eric Sosman" <Eric.Sosman@sun.com> wrote in message
news:1177612444.288279@news1nwk...
> djhong@gmail.com wrote On 04/26/07 13:47,:
>
> The reason for the do{}while(0) dodge in multi-
> statement macro expansions is to make them work right
> in contexts where just one statement is allowed.


At the expense of contexts where no statements are allowed -- only
expressions.

karl m


Eric Sosman

2007-04-26, 7:05 pm

karl malbrain wrote On 04/26/07 15:19,:
> "Eric Sosman" <Eric.Sosman@sun.com> wrote in message
> news:1177612444.288279@news1nwk...
>
>
>
> At the expense of contexts where no statements are allowed -- only
> expressions.


Right. But since there are no expressions that can
contain statements anyhow, much less the expansion of a
multi-statement macro, the expense is zero.

--
Eric.Sosman@sun.com
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com