NULL
- это макрос. Это «определяемая реализацией константа нулевого указателя;» C17dr § 7.19 3.
Целочисленное константное выражение со значением 0 или такое выражение, приведенное к типу void *
, называется константой нулевого указателя . C17dr § 6.3.2.3 3
Так что NULL
может иметь тип void *
, int
, long
, unsigned
, long long
, et c.
0
- это int
константа.
Когда все в порядке.
Назначение : оба значения ниже назначают p,q
к некоторому нулевой указатель .
void *p = 0;
void *q = NULL;
Сравнение кодов : p==q
верно, поскольку все нулевые указатели равны. Все нулевые указатели не равны адресу какого-либо объекта. !p
и !q
оба равны 1.
Когда все не в порядке.
Аргумент функции
Тип и его размер NULL
определяется реализацией.
printf("%d\n", 0); // OK - %d expects an int
printf("%d\n", NULL); // Not OK, NULL could be long, void *, etc.
printf("%p\n", NULL); // Not OK, NULL could be int, long, long long
printf("%p\n", (void*) NULL); // OK - %p expects a void*
_Generic()
Результат ниже определяется реализацией.
_Generic((NULL), \
void *: "void *", \
int: "int", \
long: "long", \
default: "TBD")
Сравнение макросов
Приведенное ниже сообщение "error: operator '*' не имеет правого операнда" для меня. #if !0
было хорошо.
#if !NULL
#error foo
#endif