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
NULLis 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
voidtype 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]".
Is every null pointer constant a null pointer?
TL;DR: no.
As you have already observed, integer constant expressions with value 0 are null pointer constants, despite not having pointer type. You have also quoted the specification's definition of null pointer: "a null pointer constant [] converted to pointer type". That means that null pointer constants of this general form ...
(void *)(<integer constant expression with value 0>)
... satisfy the definition of "null pointer". The integer constant expression is a null pointer constant itself, so the cast makes the overall expression a null pointer (in addition to being a null pointer constant).
On the other hand, null pointer constants that take the form of integer constant expressions with value 0 do not satisfy the definition of "null pointer", and there is no other provision in the language spec that would make them null pointers. Examples: 0, 0x00UL, 1 + 2 + 3 - 6.
it seems that the standard doesn't require NULL to be defined in such a way that it is simultaneously a null pointer.
Correct.
Is every null pointer constant a null pointer?
Definitely not (see above), but for most purposes, it does not matter.
(Is
NULLreally not a null pointer?)
It depends on your C implementation. The language spec allows either answer. In practice, it is a null pointer in most implementations you're likely to meet.
In case certain null pointer constants are not null pointers, would they technically be a kind of "non-null pointer"?
No. Null pointer constants that are not null pointers are not pointers at all. They are integers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With