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

Ideally you'll get rid of the macro. Macros are evil in 4 different ways: evil#1, evil#2, evil#3, and evil#4, regardless of whether they contain an if (but they're especially evil if they contain an if).

Nonetheless, even though macros are evil, sometimes they are the lesser of the other evils. When that happens, read this FAQ so you know how to make them "less bad," then hold your nose and do what's practical.

Here's a naive solution:

#define MYMACRO(a,b) \                (Bad)
    if (xyzzy) asdf()
This will cause big problems if someone uses that macro in an if statement:
if (whatever)
The problem is that the else baz nests with the wrong if: the compiler sees this:
if (whatever)
    if (xyzzy) asdf();
    else baz;
Obviously that's a bug.

The easy solution is to require {...} everywhere, but there's another solution that I prefer even if there's a coding standard that requires {...} everywhere (just in case someone somewhere forgets): add a balancing else to the macro definition:

#define MYMACRO(a,b) \                (Good)
    if (xyzzy) asdf(); \
    else (void)0
(The (void)0 causes the compiler to generate an error message if you forget to put the ; after the 'call'.)

Your usage of that macro might look like this:

if (whatever)
else                ^—this ; closes off the else (void)0 part
which will get expanded into a balanced set of ifs and elses:
if (whatever)
    if (xyzzy)
else    ^^^^^^^^—that's a do-nothing statement
Like I said, I personally do the above even when the coding standard calls for {...} in all the ifs. Call me paranoid, but I sleep better at night and my code has fewer bugs.

There is another approach that old-line C programmers will remember:

#define MYMACRO(a,b) \                (Okay)
    do { \
      if (xyzzy) asdf(); \
    } while (false)
Some people prefer the do {...} while (false) approach, though if you choose to use that, be aware that it might cause your compiler to generate less efficient code. Both approaches cause the compiler to give you an error message if you forget the ; after MYMACRO(foo,bar).