Search code examples
clanguage-lawyerstandardsnull-pointernullptr

Is a non-constant zero integer cast to `void *` still a null pointer?


The expresssion (void *)0 is called a null pointer. But how about the following:

int i = 0;
void *s = (void *)i;

Is s also a null-pointer? The C-language standard says:

6.3.2.3 Pointers

3 An integer constant expression with the value 0, such an expression cast to type void *, or the predefined constant nullptr is called a null pointer constant70). If a null pointer constant or a value of the type nullptr_t (which is necessarily the value nullptr) 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.

4 Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.

5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might produce an indeterminate representation when stored into an object.71)

According to this s would not be a null pointer?


Solution

  • It will be on any typical modern system, but it doesn't have to be. Nothing in the standard requires pointer casts to behave the same for constant expressions and non-constant expressions.

    The standard rationale document makes this explicit. From the C99 Rationale, Revision 5.10, 6.3.2.3:

    Since pointers and integers are now considered incommensurate, the only integer value that can be safely converted to a pointer is a constant expression with the value 0. The result of converting any other integer value, including a non-constant expression with the value 0, to a pointer is implementation-defined.