What C standard says?
§ 6.3.2.3 of the C99 standard says
- An integer constant expression with the value
0
, or such an expression cast to typevoid *
, is called a null pointer constant. - 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.
Explanation
- First,
0
is a null pointer constant. - When is a null pointer constant converted to a pointer type?
- assignment:
int *p = 0;
- comparison:
p == 0
orp
or!p
- dereferencing:
*p
- casting:
(void *)0
- assignment:
- So, it's safe to use
0
to initialize a pointer. (I love it)
Compiler's responsibility
C compilers recognize the value 0
(when used as a pointer) in source code to be a special value that means NULL
, which is defined in
Even when the implementation internally uses some other binary value to mean a null pointer, the compiler translates from 0
in the source code into its internal representation of a null pointer.
- The underlying architecture doesn't matter.
- If the underlying architecture has a null pointer value defined as address
0xDEADBEEF
, then it is up to the compiler to sort this mess out. - As such, even on this funny architecture,
- the following ways are still valid ways to check for a null pointer:
if (!pointer)
,if (pointer == NULL)
,if (pointer == 0)
Following are some valid ways to check for a null pointer:
if (pointer == NULL)
- the macro
NULL
is provided in the header file stddef.h. NULL
is defined to compare equal to a null pointer.- It is implementation defining what the actual definition of NULL is, as long as it is a valid null pointer constant.
if (pointer == 0)
- The integer constant literal
0
has different meanings depending upon the context in which it's used. - In all cases, it is still an integer constant with the value
0
, it is just described in different ways. - If a pointer is being compared to the constant literal
0
, then this is a check to see if the pointer is a null pointer. - This
0
is then referred to as a null pointer constant. - The C standard defines that
0
cast to the typevoid *
is both a null pointer and a null pointer constant.
if (!pointer)
- This
if
statement implicitly checks is not 0, so we reverse that to mean is 0.
The following are INVALID ways to check for a null pointer:
int mynull = 0;
...
if (pointer == mynull)
- To the compiler this is not a check for a null pointer, but an equality check on two variables.
- This might work if
mynull
never changes in the code and the compiler optimizations constant fold the0
into the if statement. - But this is not guaranteed and the compiler has to produce at least one diagnostic message (warning or error) according to the C Standard.
// even when the underlying architecture has a null pointer value defined as address `0xDEADBEEF`, following are not valid.
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
- and
0xDEADBEEF
is not 0, so according to C standard, it's not a null pointer constant in any case. - as a result,
0xDEADBEEF
will never be convert into a null pointer. - these are seen by a compiler as normal comparisons.
近期评论