Is it safe to assume that the NULL constant is zero?
NULL
will compare equal to 0
.
NULL
is very commonly a zero bit pattern. It is possible for NULL
to be a non-zero bit pattern - but not seen these days.
OP is mixing as least 4 things: NULL
, null pointer constant, null pointer, comparing a null pointer to 0. C does not define a NULL constant.
NULL
NULL
is a macro "which expands to an implementation-defined null
pointer constant" C17dr § 7.19 3
null pointer constant
An integer constant expression with the value 0, or such an expression
cast to type void
*, is called a null pointer constant. C17dr § §
6.3.2.3 3
Thus the type of a null pointer constant may be int
, unsigned
, long
, ... or void *
.
When an integer constant expression1, the null pointer constant value is 0. As a pointer like ((void *)0)
, its value/encoding is not specified. It ubiquitously does have the bit pattern of zeros, but is not specified so.
There may be many null pointer constants. They all compare equal to each other.
Note: the size of a null pointer constant, when it is an integer, may differ from the size of an object pointer. This size difference is often avoided by appending a L
or two suffix as needed.
null pointer
If a null pointer constant is converted to a pointer type, the
resulting pointer, called a null pointer, is guaranteed to compare
unequal to a pointer to any object or function. C17dr § § 6.3.2.3 3
Conversion of a null pointer to another pointer type yields a null
pointer of that type. Any two null pointers shall compare equal. C17dr
§ § 6.3.2.3 4
The type of null pointer is some pointer, either an object pointer like int *, char *
or function pointer like int (*)(int, int)
or void *
.
The value of a null pointer is not specified. It ubiquitously does have the bit pattern of zeros, but is not specified so.
All null pointer compare as equal, regardless of their encoding.
comparing a null pointer to 0
if(!ptr)
is the same as if(!(ptr != 0))
. When the pointer ptr
, which is a null pointer, is compared to 0, the zero is converted to a pointer, a null pointer of the same type: int *
. These 2 null pointers, which could have different bit patterns, compare as equal.
So when it is not safe to assume that the NULL constant is zero?
NULL
may be a ((void*)0)
and its bit pattern may differ from zeros. It does compare equal to 0 as above regardless of its encoding. Recall pointer compares have been discussed, not integer compares. Converting NULL
to an integer may not result in an integer value of 0 even if ((void*)0)
was all zero bits.
printf("%ju\n", (uintmax_t)(uintptr_t)NULL); // Possible not 0
Notice this is converting a pointer to an integer, not the case of if(!ptr)
where a 0 was converted to a pointer.
The C spec embraces many old ways of doing things and is open to novel new ones. I have never came across an implementation where NULL
was not an all zeros bit pattern. Given much code exist that assumes NULL
is all zero bits, I suspect only old obscure implementations ever used a non-zero bit-pattern NULL
and that NULL
can be all but certain to be an all zero bit pattern.
1 The null pointer constant is 1) an integer or 2) a void*
. "When an integer ..." refers to the first case, not a cast or conversion of the second case as in (int)((void*)0)
.