Каково значение неопределенной константы, используемой в #if?

Мой препроцессор, кажется, предполагает, что неопределенные константы равны 0 для оценки #if условия.

Можно ли полагаться на это, или неопределенные константы дают неопределенное поведение?

2 ответа

Решение

Да, на это можно положиться. Стандарт C99 определяет в §6.10.1 №3:

После выполнения всех замен из-за расширения макроса и определенного унарного оператора все оставшиеся идентификаторы заменяются числом pp. 0

редактировать

Извините, я подумал, что это был вопрос C; тем не менее, ничего страшного, эквивалентный раздел в стандарте C++ (§16.1 ¶4) гласит:

После выполнения всех замен из-за расширения макроса и определенного унарного оператора все оставшиеся идентификаторы и ключевые слова, кроме true а также false, заменены на номер pp 0

Единственная разница заключается в разной обработке true а также false, которые в C не нуждаются в особой обработке, в то время как в C++ они имеют особое значение даже на этапе предварительной обработки.

Идентификатор, который не определен как макрос, преобразуется в 0 до того, как выражение будет оценено.

Исключением является идентификатор true, который преобразуется в 1, Это специфично для препроцессора C++; в C этого не происходит, и вам нужно будет включить <stdbool.h> использовать true таким образом, в этом случае он будет определен как макрос, и никакой специальной обработки не требуется.

OP спрашивал конкретно о препроцессоре C, и первый ответ правильно относился к спецификации препроцессора C. Но некоторые другие комментарии, кажется, стирают различие между препроцессором C и компилятором C. Чтобы было ясно, это две разные вещи с отдельными правилами, и они применяются в двух разных проходах.

#if 0 == NAME_UNDEFINED
int foo = NAME_UNDEFINED;
#endif

В этом примере будет успешно выведено определение foo, потому что препроцессор C оценивает NAME_UNDEFINED как 0 как часть условного выражения, но генерируется ошибка компилятора, потому что инициализатор не оценивается как условное выражение, а затем компилятор C оценивает его как неопределенный символ.

Другие вопросы по тегам