2009-09-03 4 views
3

Я хочу сделать макрос, который будет вводить код, как:Как создать макрос с несколькими строками кода?

if (foo) { 
[Bar fooBar]; 
} 

, а затем, где когда-либо мне нужно, что я ставлю FOOBAR в коде. Не уверен, но во время компиляции компилятор заменяет это фактическим кодом, как в приведенном выше примере. Может быть, есть что-то другое, чем макрос, который я мог бы использовать для этого?

ответ

8

Используйте \, чтобы избежать каждого разрыва строки, который вы хотите быть частью макроса.

Однако имейте в виду, что использование таких макросов может скрыть структуру, если вы не будете осторожны. С вашего примера:

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), как вы хотели.

5

определить макрос на нескольких строках путем добавления \ в конец каждой строки, кроме последней. К сожалению, макрос будет расширяться до одной строки, когда вы его используете.

+0

Я делаю здесь большое предположение, что макросы Object-C такие же, как и обычные макросы C. –

+1

Да, язык препроцессора C не изменяется в Objective-C. –