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]".
the following are null pointer constants which are not null pointers
and then you followIs every null pointer constant a null pointer?
. You stated the answer. – Housecoatvoid
did not exist, so there have been#define NULL 0
. So that bothNULL (void*)0
andNULL 0
are correct, there is this "null pointer constant is an integer or pointer". Something not mentioned is that it is constant expressions with the value 0, think about1-1
1*0
etc. Also see open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf page 144 . Also if one does not know #49615838 – Housecoatnullptr
from C23. The keyword nullptr denotes a predefined null pointer constant. It is a non-lvalue of type nullptr_t. nullptr can be converted to a pointer types or bool, where the result is the null pointer value of that type or false respectively. – TriodeNULL
to a pointer type when passing it to a variadic function, e.g. the last argument inexecl()
. – Oxley