From the C17 draft (6.3.2.3 ¶3):
An integer constant expression with the value 0, or such an expression cast to type
void *
, is called a null pointer constant.67) 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.67)The macro
NULL
is defined in<stddef.h>
(and other headers) as a null pointer constant [...].
From this, it follows that the following are null pointer constants: 0
, 0UL
, (void *)0
, (void *)0UL
, NULL
.
It further follows that the following are null pointers: (int *)0
, (int *)0UL
, (int *)(void *)0
, (int *)(void *)0UL
, (int *)NULL
. Interestingly, none of these are "null pointer constants"; see here.
The following null pointer constants are null pointers (because void *
is a pointer type and 0
and 0UL
are null pointer constants): (void *)0
, (void *)0UL
. In this regard, according to the C17 draft (6.2.5 ¶19-20):
The
void
type comprises an empty set of values; it is an incomplete object type that cannot be completed.
[...]
A pointer type may be derived from a function type or an object type, called the referenced type. [...] A pointer type is a complete object type.
void
is not a pointer type itself, and it is an incomplete object type. But void *
is a pointer type.
But it seems that the following are null pointer constants which are not null pointers (because there is no cast to a pointer type): 0
, 0UL
, NULL
. (To be precise, while the standard only requires that NULL
be defined as "a null pointer constant", it would be permissible to define it as a null pointer constant which is also a null pointer. But it seems that the standard doesn't require NULL
to be defined in such a way that it is simultaneously a null pointer.)
Is every null pointer constant a null pointer? (Is NULL
really not a null pointer?)
Finally (and somewhat tongue-in-cheek): In case certain null pointer constants are not null pointers, would they technically be a kind of "non-null pointer"? (This wording appears in some places in the standard.) Note that linguistically we have a so-called bracketing paradox; we can read this as "[non-null] pointer" or "non-[null pointer]".