Используйте \, чтобы избежать каждого разрыва строки, который вы хотите быть частью макроса.
Однако имейте в виду, что использование таких макросов может скрыть структуру, если вы не будете осторожны. С вашего примера:
if (bar)
FOOBAR();
else
do_something_else();
Угадайте, что это расширяет. Наверное, не то, что вы думаете. Вот что видит компилятор (с отступом):
if (bar)
if (foo)
{
[Bar fooBar];
}
;
else
do_something_else();
Упс! Эта точка с запятой представляет собой отдельный пустой оператор. Каждый if
принимает только одно утверждение; первый оператор if
является вторым if
, а второй оператор if
представляет собой составной оператор ({…}
), поэтому они оба выполнили свою квоту, оставив точку с запятой.
Таким образом, точка с запятой не привязана к if
- это безусловное. Это вызывает синтаксическую ошибку, когда вы затем пытаетесь применить else
к безусловному утверждению.
Починок, некрасивые, как оно есть, чтобы обернуть содержимое FOOBAR
в do…while
заявления:
#define FOOBAR() \
do { \
if (foo) \
[Bar fooBar]; \
} while(0) /*semicolon omitted*/
Потому что мы выходим из точки с запятой в определении макроса, то do…while
является несогласованным заявлением, так что точка с запятой за пределами использования макроса будет привязана к ней. Тогда наш расширен код выглядит следующим образом:
//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();
else
Теперь связывается с if (bar)
, как вы хотели.
Я делаю здесь большое предположение, что макросы Object-C такие же, как и обычные макросы C. –
Да, язык препроцессора C не изменяется в Objective-C. –