#ifndef NULL
#define NULL NULL
#endif
Этот код компилирует в gcc без предупреждений/ошибок. Кто-то может объяснить, что препроцессор делает здесь?
Везде, где компилятор видит текст "NULL", он заменит его текстом "NULL". Это все равно, что делать поиск и замену в коде "NULL" и замену на "NULL". Это не незаконно, просто странно :)
.Единственной возможной причиной для этого было бы сделать это до, включая заголовочные файлы, которые сами по себе делают что-то вроде
#ifndef NULL
#define NULL (void *)0
#endif
Это остановило бы определение NULL таким образом.
. Я видел случаи, когда подобный код приносил значение из пространства имен компилятора ("пространства имен" вообще, а не C++ namespace
) в пространство имен препроцессора, например:
// In the compiler namespace, not in the preprocessor namespace
static int const FOO = 1234;
// Bring the constant into the preprocessor namespace as well
#ifndef FOO // <---- FOO really is undefined here.
#define FOO FOO
#endif
Действительно уродливые вещи.
Лично я не нашел использования для такого рода вещей, но все же существую.
EDIT: Пока я это видел, я не знаю, зачем это нужно, кроме проверки, не определено ли "FOO
" как символ препроцессора где-нибудь в другом коде; возможно, при работе с каким-нибудь наследственным кодом. Кто-нибудь?
Это нормально:
#ifndef JON_SKEET
#define JON_SKEET JON_SKEET
#endif
Это тоже компилируется. Это связано с тем, что препроцессор просто делает бездумную замену. То, что он заменяет, и то, что он заменяет, не обязательно должно быть валидными идентификаторами.
Подумайте об этом так: откройте окно поиска и замены редактора и введите "NULL" в обоих полях Replace
и Replace with
. Это не даст никакой ошибки или предупреждения и "сработает", даже если на самом деле ничего не делает. Препроцессор делает то же самое.
Очевидно, что при попытке использовать его:
'JON_SKEET' undeclared (first use in this function) (Each undeclared identifier is reported only once for each function it appears in.)
В ответ на вопрос, что делает препроцессор:
Если нет предыдущего кода, который отменяет NULL, то он полностью пропускает #define NULL
. NULL почти наверняка уже определено. В Си++ использование 0 предпочтительнее из-за более жесткой проверки типов в Си++. Если нужно использовать NULL, то лучше всего объявить const int NULL = 0;
(см. раздел 5.1.1 Stroustrup).
Очевидно, что это используется не как макрос, а как флаг компиляции. Есть ли другие области кода, где вы видите #ifdef NULL
или #ifndef NULL
?
Очень странно использовать "NULL", конкретно, как такой флаг, но я видел более странные (#define TRUE FALSE
)...
, разве это не означает, что NULL - это последовательность символов "NULL" ?
.