Every statement in C and C++
must be terminated with a semicolon.
x = 12;
However, a multi-statement
block is not; it is delimited by curly braces.
1 2 3 4 5
|
{
x = 12;
y = 9;
std::cout << (x + y) << "\n";
}
|
You can place a multi-statement block anywhere you wish to place a single statement:
1 2
|
if (x == 12)
std::cout << "Yeah!\n";
|
1 2 3 4 5
|
if (x == 12)
{
x = 0;
std::cout << "No twelves allowed.\n";
}
|
Notice the difference between the two: one has a semicolon at the end of the if-statement and one does not.
Now imagine a macro that expands to a multi-statement block, which you
also terminate with a semicolon:
1 2 3 4 5 6 7 8 9
|
#define MULTI_STATEMENT_MACRO( arg ) \
{ \
foo; \
bar; \
baz; \
}
if (...)
MULTI_STATEMENT_MACRO("hello") ;
|
if (...)
{
foo;
bar;
baz;
} ; |
Notice that extra semicolon after the multi-statement block? It is
not part of the
if statement. It is a new statement. (A "null statement", since there is nothing there but the semicolon.)
However, an
else statement clause requires an
if statement
with no interleaving statements.
Clearly, the following is not legal:
1 2 3 4
|
if (...)
x = 12;
;
else x = 13;
|
Likewise, the following is not legal:
1 2 3 4 5 6 7
|
if (...)
{
x = 12;
y = -7;
}
;
else x = 13;
|
That lone "null statement" between the
if and
else is a clear problem.
The macro trick you read about is to turn the multi-statement block into a single statement block that
contains a multi-statement block. What better than a
do..while statement: it is a single statement that contains a statement or statement block:
1 2 3 4 5 6 7
|
if (...)
do {
foo;
bar;
baz;
} while (0) ;
else x = 13;
|
In this case, the semicolon on line 6 terminates the
do..while statement, and the
else clause immediately follows, making a well-formed
if..else statement.
Hope this helps.
}