Когда нам нужно #ifdef перед #undef?
Во многих файлах C и С++ я видел такие макросы как:
#ifdef X
#undef X // no statements in between
#endif
Я чувствую, что достаточно просто написать:
#undef X
Если макрос X
не был определен, то #undef
не должен иметь эффекта.
Можно ли оставить автономный #undef
, если я хочу только определить макрос? Во всяком случае, это плохо влияет на кодирование?
Ответы
Ответ 1
См. ИСО C99 6.10.3.5, пункт 2.
Директива предварительной обработки формы
# undef identifier new-line
заставляет указанный идентификатор больше не определяться как имя макроса. Он игнорируется, если указанный идентификатор в настоящее время не определен как имя макроса.
Даже Visual С++ 6 (что было известно о соблюдении плохих стандартов) позволяет:
Вы также можете применить директиву #undef
к идентификатору, у которого нет предыдущего определения. Это гарантирует, что идентификатор undefined. Замена макроса не выполняется в операторах #undef
.
Ответ 2
Я уверен, что это артефакт истории. Как упоминалось в jdigital ответе, второе издание K & R говорит
Неправильно применять #undef к неизвестному идентификатору.
Однако это предложение не относится к изданию 1978 года. Я почти уверен, что предварительные стандартные компиляторы часто выдавали ошибку, если вы попытались сделать #undef
макрос undefined.
Кроме того, ANSI C Обоснование говорит:
Явным образом разрешено #undef макрос, который не имеет текущего определения.
Я бы предположил, что если бы это была уже универсальная практика, не было бы необходимости вызывать ее в обосновании.
Все, что сказано, в современном коде не нужно, но на самом деле это тоже не повредит.
Ответ 3
Керниган и Ричи (2-е издание) согласны с вами.
EDIT: цитата из источника (раздел A12.3):
Линия управления формы
# undef
идентификатор
приводит к забыванию определения препроцессора идентификатора. Если неверно применять #undef
к неизвестному идентификатору.