If I write
int zero = 0;
void *p1 = (void *)0;
void *p2 = (void *)(int)0;
void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0);
void *p4 = (void *)zero; // For reference, this is a pointer to address zero
void *p5 = 0; // For reference, this is a null pointer
void *p6 = NULL; // For reference, this is a null pointer
void *p7 = nullptr; // For reference, this is a null pointer (C++11)
static const int static_zero_1 = 0; // Is this a literal zero when used?
static const int static_zero_2 = 1 - 1; // No "literals 0" per se... is it?
void *p8 = (void *)static_zero_1; // I have seen weird substitution rules...
void *p9 = (void *)static_zero_2; // do they apply for NULL too?
which of p1
, p2
, and p3
(edit: I added p8
and p9
) would be null pointers (i.e. == NULL
, may or may not be address zero), and which of them would be pointers with the address zero (may or may not be == NULL
)?
If the answer is different in C and C++, what is it in each of them?
In C++11, all of them. Per paragraph 4.10/1 of the C++11 Standard:
Therefore, according to the terminology of the Standard, everything which is a constant (integral) expression and evaluates to
0
is a null pointer constant (not a null pointer, yet). The only one which is not a constant expression that evaluates to0
or a prvalue of typenullptr_t
in your example iszero
, because it is not a constant expression.The paragraph continues:
So in your example all the pointers except
p4
are null pointer values and compare equal among themselves.And to make Andy's answer complete with C:
From the C99 Standard:
So any integer constant expression which evaluates to
0
is a null pointer constant and can be converted to aNULL
pointer. Effectively in your example, all pointers through exceptp4
,p8
andp9
are null pointers.p4
,p8
andp9
need not be null pointers since their initialization is not a constant expression because it contains variables (even ifconst
qualified).Here's another answer about
NULL
in C++, for the record.p1
andp2
are null pointers;p3
is implementation defined, and may be something else. (A comma operator cannot be part of a constant expression. And the mapping of a non-constant integral value 0 to a pointer is implementation defined.) C is identical to C++ here.p8
andp9
are both null pointers in C++, but not in C.With regards to your comment on
static_zero_2
, there is no requirement in either language that a literal zero be present, anywhere. g++ definesNULL
as the compiler built-in__null
, for example, and you can use(1 - 1)
, or'\0'
, or any other constant expression evaluating to 0.