The definition in the C standard of a possible expansion of the macro NULL is quite loose; it just has to be a null pointer constant. Therefore, a C compiler could choose any of the following for it: 0U, 0, '\0', 0UL, 0L, 0ULL, 0LL, or (void * )0. It is important that the type behind NULL is not prescribed by the C standard. Often, people use it to emphasize that they are talking about a pointer constant, which it simply isn’t on many platforms. Using NULL in a context that we have not mastered completely is even dangerous. This will in particular appear in the context of functions with a variable number of arguments.
NULL hides more than it clarifies. Either use 0 or, if you really want to emphasize that the value is a pointer, use the magic token sequence (void * )0 directly.
https://www.gnu.org/software/libc/manual/html_node/Null-Poin... says:
The preferred way to write a null pointer constant is with NULL. You can also use 0 or (void * )0 as a null pointer constant, but using NULL is cleaner because it makes the purpose of the constant more evident.
If you use the null pointer constant as a function argument, then for complete portability you should make sure that the function has a prototype declaration. Otherwise, if the target machine has two different pointer representations, the compiler won’t know which representation to use for that argument. You can avoid the problem by explicitly casting the constant to the proper pointer type, but we recommend instead adding a prototype for the function you are calling.
https://man.openbsd.org/style says:
NULL is the preferred null pointer constant. Use NULL instead of (type * )0 or (type * )NULL in all cases except for arguments to variadic functions where the compiler does not know the type.
---
Readers: what is your take on it and why?