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