In ISO-C99, there are two types of null pointer constants: integer constant expression of value 0
- eg 0
, 1 - 1
, (int)0.0
- and such expressions cast to void *
- eg (void *)0
, which is often used to define NULL
.
Converting a null pointer constant to an arbitrary pointer type yields a null pointer of that type. This conversion is implicit, but may actually involve address translation as the standard doesn't require null pointers to have the bit-representation 0.
This conversion is also defined for function pointer types, even if it's normally illegal to convert object pointers to function pointers:
void (*foo)(void) = (void *)0; // valid
void *bar = 0; // valid
void (*baz)(void) = (void (*)(void))bar; // invalid even with explicit cast
This also means that you can use 0
to initialize any scalar type without casting, and it's the only value for which this is true: Converting 0
to pointer types will always yield a null pointer, whereas converting any other integral value is possible, but requires explicit casting, has an implementation-defined result and might fail due to alignment or address space restrictions.