C doesn't allow bare blocks.
Hmmmm.... what do you mean by that? Why doesn't a C "compound statement"
qualify as a "bare block"?
So if you have a multi-line macro, and a
controlling statement
eg
#define MYMACRO() printf("Hello");printf("World");
if(x == y)
MYMACRO();
"World" will be printed if x != y, which probably isn't what you want.
OTOH, if the macro were
#define MYMACRO() { printf("Hello"); printf("World"); }
then
if (x==y)
MYMACRO();
would work as expected.
The do ... while(0) is a hack to get round that oversight. It works very
well.
I think that you really wanted to illustrate
if (x == y)
MYMACRO();
else
do_something_else();
If MYMACRO() expanded to a full statement (either a semi-colon terminated
single statement, or a brace bracketed compound statement), the trailing
semicolon from the unexpanded invocation (the semicolon at the end
of "MYMACRO();") would be taken as a new (empty) statement at the same
level as the "if" statement.
This, in turn, would "unpair" the following "else" statement from the "if"
statement, causing a syntax error upon compilation.
The "do { } while(0)" macro expansion takes advantage of the syntax of the
do/while verb, along with the behaviour of the while(0) condition, to
permit a single pass through the "do {} while()" logic (like the compound
statement would permit), while permitting (requiring) the macro invocation
to be treated as a single statement, terminated with a semicolon. Thus, the
semicolon that follows the MYMACRO() invocation is paired with the while()
clause of the expanded macro, and the "else" is left to be properly paired
with the preceding "if".
The drawback to using a "do {} while(0)" macro is that the invocation /must/
be terminated with a semicolon. This means that it is /not/ proper to use
this sort of macro as anything other than the rightmost rvalue of a
statement. In other words, you can't use it as
a = MYMACRO() + 6;
or even
a = MYMACRO(), 10;
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------