Когда нам нужен #ifdef перед #undef? - PullRequest
31 голосов
/ 01 февраля 2012

Во многих файлах C и C ++ я видел такие макросы:

#ifdef X
#undef X  // no statements in between
#endif

Мне кажется, достаточно написать:

#undef X

Если макрос X не было определено, тогда #undef не должно иметь никакого эффекта.

Это нормально , чтобы поставить автономный #undef, если я хочу только undefine макрос?В любом случае это делает практику кодирования плохой?

Ответы [ 3 ]

22 голосов
/ 01 февраля 2012

См. ISO C99 6.10.3.5, параграф 2.

Директива предварительной обработки вида

# undef identifier new-line

приводит к тому, что указанный идентификатор больше не определяется как имя макроса.Он игнорируется, если указанный идентификатор в настоящее время не определен как имя макроса.

Четный Visual C ++ 6 (который был печально известен плохим соответствием стандартам) позволяет это:

Вы также можете применить директиву #undef к идентификатору, который не имеет предыдущего определения.Это гарантирует, что идентификатор не определен.Замена макроса не выполняется в операторах #undef.

11 голосов
/ 01 февраля 2012

Я уверен, что это артефакт истории. Как уже упоминалось в ответе jdigital , во 2-м издании K & R говорится:

Неправильно применять #undef к неизвестному идентификатору.

ОднакоЭто предложение отсутствует в издании 1978 года.Я почти уверен, что стандартные компиляторы часто выдают ошибку, если вы попытаетесь #undef неопределенный макрос.

Кроме того, Обоснование ANSI C гласит: :

Явно разрешено #undef макрос, который не имеет текущего определения.

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

Все это говорит, что в современном коде это не нужно, но это не тактоже очень больно.

9 голосов
/ 01 февраля 2012

Керниган и Ричи (2-е издание) согласны с вами.

РЕДАКТИРОВАТЬ: цитата из источника (раздел A12.3):

Контрольная строка в форме

# undef идентификатор

приводит к тому, что определение препроцессора идентификатора будет забыто.Если не ошибочно применять #undef к неизвестному идентификатору.

...