How to create a macro with multiple lines of code?

cocoa, cocoa-touch, iphone, objective-c

Solution

Use \ to escape each line-break you want to be part of the macro.

However, be aware that using macros like this can hide structure if you aren't careful. Taking your example:

if (bar)
    FOOBAR();
else
    do_something_else();

Guess what this expands to. Probably not what you think. Here's what the compiler sees (indentation adjusted):

if (bar)
    if (foo)
        {
            [Bar fooBar];
        }
;
    else
        do_something_else();

Oops! That semicolon is a separate, empty statement. Each `if` takes only one statement; the first `if`'s statement is the second `if`, and the second `if`'s statement is the compound statement (`{…}`), so they have both met their quota, leaving the semicolon out.

So the semicolon is not bound to an `if`—it's unconditional. That causes a syntax error when you then try to apply the `else` to an unconditional statement.

The fix, ugly as it is, is to wrap the contents of `FOOBAR` in a `do…while` statement:

#define FOOBAR()       \
    do {                \
        if (foo)         \
            [Bar fooBar]; \
    } while(0) /*semicolon omitted*/

Because we leave out the semicolon in the macro definition, the `do…while` is an unterminated statement, so that the semicolon outside the macro usage will bind to it. Then our expanded code looks like this:

//First, the unexpanded code again
if (bar)
    FOOBAR();
else
    do_something_else();

//Expanded
if (bar)
    do
        {
            if (foo)
                [Bar fooBar];
        }
    while(0);
else
    do_something_else();

The `else` now binds to `if (bar)`, as you intended.

Problem

I want to make a macro which will inject some code, like: ``` if (foo) { [Bar fooBar]; } ``` and then, where ever I need that, I put FOOBAR in the code. Not sure, but at compile time then the compiler replaces this with the actual code like in the example above. Maybe there's something different than a macro I could use for this?

Original source