C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 39:
[39.5] What should be done with macros that have multiple lines?

Answer: Choke, gag, cough. Macros are evil in 4 different ways: evil#1, evil#2, evil#3, and evil#4. Kill them all!! (Just kidding.)

Seriously, sometimes you need to use them anyway, and when you do, read this to learn some safe ways to write a macro that has multiple statements.

Here's a naive solution:

#define MYMACRO(a,b) \                (Bad)
    statement1; \
    statement2; \
    ... \
    statementN;
This can cause problems if someone uses the macro in a context that demands a single statement. E.g.,
while (whatever)
    MYMACRO(foo, bar);
The naive solution is to wrap the statements inside {...}, such as this:
#define MYMACRO(a,b) \                (Bad)
    { \
        statement1; \
        statement2; \
        ... \
        statementN; \
    }
But this will cause compile-time errors with things like the following:
if (whatever)
    MYMACRO(foo, bar);
else
    baz;
...since the compiler will see:
if (whatever)
{
    statement1;
    statement2;
    ...
    statementN;
} ; else
^^^^^^^^—compile-time error!
    baz;
One solution is to use a do { <statements go here> } while (false) pseudo-loop. This executes the body of the "loop" exactly once. The macro might look like this:
#define MYMACRO(a, b) \                (Okay)
    do { \
        statement1; \
        statement2; \
        ... \
        statementN; \
    } while (false)      intentionally not including a ; here
The ; gets added by the macro's user, such as:
if (whatever)
    MYMACRO(foo, bar);
else                 ^—the user of MYMACRO() adds the ; here
    baz;
After expansion, the compiler will see this:
if (whatever)
    do {
        statement1;
        statement2;
        ...
        statementN;
    } while (false);
else               ^—this ; came from the user's code, not from MYMACRO() itself
    baz;
There is an unlikely but possible downside to the above approach: historically some C++ compilers have refused to inline-expand any function containing a loop. If your C++ compiler has that limitation, it will not inline-expand any function that uses MYMACRO(). Chances are this won't be a problem, either because you don't use MYMACRO() in any inline functions, or because your compiler (subject to all its other constraints) is willing to inline-expand functions containing loops (provided the inline function meets all your compiler's other requirements). However, if you are concerned, do some tests with your compiler: examine the resulting assembly code and/or perform a few simple timing tests.

If you have any problems with your compiler's willingness to inline-expand functions containing loops, you can change MYMACRO()'s definition to if (true) {...} else (void)0

#define MYMACRO(a, b) \
    if (true) { \
        statement1; \
        statement2; \
        ... \
        statementN; \
    } else
        (void)0      intentionally not including a ; here
After expansion, the compiler will see a balanced set of ifs and elses):
if (whatever)
    if (true) {
        statement1;
        statement2;
        ...
        statementN;
    } else
        (void)0;
else    ^^^^^^^^—a do-nothing statement
    baz;
The (void)0 in the macro definition forces users to remember the ; after any usage of the macro. If you forgot the ; like this...
foo();
MYMACRO(a, b)
bar();       ^—whoops, forgot the ; here
baz();
...then after expansion the compiler would see this:
foo();
if (true) {
    statement1; \
    statement2; \
    ... \
    statementN; \
} else
    (void)0 bar();
            ^—fortunately(!) this will produce a compile-time error-message
baz();
Even though the specific error message is likely to be confusing, it will at least cause the programmer to notice that something is wrong. That's a lot better than the alternative: without the (void)0 in the MYMACRO() definition, the compiler would silently generate the wrong code: the bar() call would never be called, since it would erroneously be on the unreachable else branch of the if.