#define NULL NULL - PullRequest
       30

#define NULL NULL

8 голосов
/ 23 декабря 2009
#ifndef NULL
#define NULL NULL
#endif

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

Ответы [ 7 ]

19 голосов
/ 23 декабря 2009

Везде, где компилятор видит текст «NULL», он заменяет его текстом «NULL». Это похоже на поиск и замену в вашем коде слова «NULL» и замену на «NULL». Не незаконно, просто странно :) 1001 *

14 голосов
/ 23 декабря 2009

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

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

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

5 голосов
/ 23 декабря 2009

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

#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.)
3 голосов
/ 23 декабря 2009

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

Действительно ужасные вещи.

Лично я не нашел применения для такого рода вещей, но тем не менее существует.


РЕДАКТИРОВАТЬ : Хотя я видел это, я не знаю, почему это было бы полезно, кроме проверки, определен ли "FOO" как символ препроцессора где-то еще в коде; возможно, имея дело с каким-то устаревшим кодом. Кто-нибудь?

2 голосов
/ 23 декабря 2009

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

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

1 голос
/ 23 декабря 2009

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

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

0 голосов
/ 23 декабря 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...