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?