#define директивный вопрос - PullRequest
0 голосов
/ 17 июля 2009

У меня есть следующий код:

#define checkLiteMessage    \
{   \
    #ifdef LITE_VERSION \
    if (alertView.tag == 100)   \
    {   \
        if (buttonIndex == 1)   \
        [ [UIApplication sharedApplication] openURL: buyAppLink];   \
        [alertView release];    \
        return; \
    }   \
    #endif  \
}   \

Я хочу, чтобы при каждом вызове checkLiteMessage включался следующий код:

    #ifdef LITE_VERSION
    if (alertView.tag == 100)
    {
        if (buttonIndex == 1)
        [ [UIApplication sharedApplication] openURL: buyAppLink];
        [alertView release];
        return;
    }
    #endif

В чем моя проблема? Почему этот код не компилируется?

Спасибо.

Ответы [ 4 ]

8 голосов
/ 17 июля 2009

Вы указали макрос с продолжением строки, что является правильным. Однако это означает, что оператор #ifdef находится не в начале строки, поэтому препроцессор этого не сделает.

Вы не можете встроить #ifdef в макрос. Вы можете изменить это:

#ifdef LITE_VERSION
#define checkLiteMessage  do {   \
    if (alertView.tag == 100)   \
    {   \
        if (buttonIndex == 1)   \
        [ [UIApplication sharedApplication] openURL: buyAppLink];       \
        [alertView release];    \
        return; \
    }   \ 
} while(0)
#else
#define checkLiteMessage do { ; } while (0)
#endif

Я добавлю, что помещение выражения return внутри макроса является довольно злым и запутает всех. Не делай этого.

3 голосов
/ 17 июля 2009

Проблема в том, что вы не можете включить директивы препроцессора в макрос. Вы можете сделать это вместо этого:

#ifdef LITE_VERSION
#define checkLiteMessage    \
{   \
    if (alertView.tag == 100)   \
    {   \
        if (buttonIndex == 1)   \
        [ [UIApplication sharedApplication] openURL: buyAppLink];       \
        [alertView release];    \
        return; \
    }   \
}
#else
#define checkLiteMessage
#endif

Также убедитесь, что строка «return» выполняет то, что вы думаете (здесь она выходит из функции, вызывающей checkLiteMessage, а не только из макроса (макрос не может быть «завершен»).

1 голос
/ 17 июля 2009

Комбинация обратной косой черты и перевода строки эквивалентна отсутствию букв, поэтому

#define x   y \
   z

эквивалентно

#define x y z

Кроме того, согласно стандарту директивы препроцессора в теле макроса не раскрываются и не интерпретируются, и #ifdef передается компилятору вместо условного удаления кода между ними.

Вы можете проверить это поведение, создав файл a.c с содержимым

#define x y \
     z

#define v  \
       #ifdef E

x

v

и предварительной обработки с помощью команды gcc -E a.c.

В вашей ситуации вам нужно сделать

 #ifdef LITE_VERSION 
 #define checkLiteMessage    \
 {   \
     if (alertView.tag == 100)   \
     {   \
         if (buttonIndex == 1)   \
         [ [UIApplication sharedApplication] openURL: buyAppLink];       \
         [alertView release];    \
         return; \
     }   \
 }   
 #else
 #define checkLiteMessage
 #endif      
0 голосов
/ 17 июля 2009

Препроцессор только однопроходный. Итак, последовательность #ifdef попадает в ваш компилятор, вызывая ошибку. Сделайте это функцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...