According to the language definition, a constant 0 in a pointer context is converted into a null pointer at compile time.
Indeed even if the stored bit pattern for the 'NULL' pointer isn't all zero [1], then the literal 0 denotates a NULL pointer. So: char *p = 0; if (*(int *)&p != 0) printf(...); can call printf.
It is also valid to '#define NULL (void *)0' that value is compatible with function pointers - even though a function pointer can't be assigned to a 'void *' variable.
David
[1] I don't know of any such C implementation, but I some mainframe OS have used the all 1 bit pattern for illegal pointers.