Почему define (X) не работает в определении препроцессора без пробела? - PullRequest
4 голосов
/ 20 марта 2010

Определение препроцессора, включающее defined(X), никогда не будет иметь значение true, но (defined X) будет. Это происходит в MSVC9; Я не тестировал другие препроцессоры. Простой пример:

#define FEATURE0 1
#define FEATURE1 0
#define FEATURE2 1

#define FEATURE3 (FEATURE0 && !FEATURE1 && (defined(FEATURE2)))
#define FEATURE4 (FEATURE0 && !FEATURE1 && (defined FEATURE2))
#define FEATURE5 (FEATURE0 && !FEATURE1 && (defined (FEATURE2)))

#if FEATURE3
#pragma message("FEATURE3 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined(FEATURE2)))
#pragma message("FEATURE3 Enabled (Fallback)")
#endif

#if FEATURE4
#pragma message("FEATURE4 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined FEATURE2))
#pragma message("FEATURE4 Enabled (Fallback)")
#endif

#if FEATURE5
#pragma message("FEATURE5 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined (FEATURE2)))
#pragma message("FEATURE5 Enabled (Fallback)")
#endif

Выходные данные компилятора:

1> FEATURE3 включен (резерв)
1> FEATURE4 включен
1> FEATURE5 включен

Рабочие случаи: defined (X), defined( X ) и defined X.
Разбитый корпус: defined(X)

Почему defined оценивается иначе, когда часть определения, как в случаях #if в примере, по сравнению с прямой оценкой, как в случаях #elif в примере?

Ответы [ 3 ]

5 голосов
/ 20 марта 2010

defined относится только к #if и #elif. При использовании его через расширение макроса поведение не определено.

3 голосов
/ 20 марта 2010

Помните, что defined(X) не интерпретируется как вызов функции (а-ля sizeof(X)), он анализируется специальным синтаксическим анализатором языка. Этот синтаксический анализатор распознает defined как модификатор оператора if, а не как независимую сущность. Когда вы используете defined(FEATURE2), он воспринимается не defined как ключевое слово, а как обычный объект или #define d (что в данном случае не существует, что приводит к вашей ошибке) Позже, когда вы используете его внутри оператора elif, синтаксический анализатор обрабатывает его как правильное ключевое слово.

Если честно, я не знал, что defined(SOMETHING) сработает в любом случае.

1 голос
/ 20 марта 2010

Согласно 6.10.1.3 в спецификации C99, ключевое слово определено распознается, только если оно появляется непосредственно в выражении #if перед любым расширением макроса в этом выражении. Если в результате расширения макроса ключевое слово определено , результаты не определены.

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