ПУСТОЙ УКАЗАТЕЛЬ ПУСТОГО УКАЗАТЕЛЯ #define

#ifndef NULL
#define NULL NULL
#endif

Этот код компилирует в gcc без предупреждений/ошибок. Кто-то может объяснить, что препроцессор делает здесь?

8
задан SilentGhost 30 May 2010 в 20:16
поделиться

7 ответов

Везде, где компилятор видит текст "NULL", он заменит его текстом "NULL". Это все равно, что делать поиск и замену в коде "NULL" и замену на "NULL". Это не незаконно, просто странно :)

.
19
ответ дан 5 December 2019 в 04:41
поделиться

Единственной возможной причиной для этого было бы сделать это до, включая заголовочные файлы, которые сами по себе делают что-то вроде

#ifndef NULL
#define NULL (void *)0
#endif

Это остановило бы определение NULL таким образом.

.
14
ответ дан 5 December 2019 в 04:41
поделиться

Я видел случаи, когда подобный код приносил значение из пространства имен компилятора ("пространства имен" вообще, а не 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" как символ препроцессора где-нибудь в другом коде; возможно, при работе с каким-нибудь наследственным кодом. Кто-нибудь?

3
ответ дан 5 December 2019 в 04:41
поделиться

Это нормально:

#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.)
5
ответ дан 5 December 2019 в 04:41
поделиться

В ответ на вопрос, что делает препроцессор:

Если нет предыдущего кода, который отменяет NULL, то он полностью пропускает #define NULL . NULL почти наверняка уже определено. В Си++ использование 0 предпочтительнее из-за более жесткой проверки типов в Си++. Если нужно использовать NULL, то лучше всего объявить const int NULL = 0; (см. раздел 5.1.1 Stroustrup).

.
1
ответ дан 5 December 2019 в 04:41
поделиться

Очевидно, что это используется не как макрос, а как флаг компиляции. Есть ли другие области кода, где вы видите #ifdef NULL или #ifndef NULL?

Очень странно использовать "NULL", конкретно, как такой флаг, но я видел более странные (#define TRUE FALSE)...

...
2
ответ дан 5 December 2019 в 04:41
поделиться

, разве это не означает, что NULL - это последовательность символов "NULL" ?

.
0
ответ дан 5 December 2019 в 04:41
поделиться