The defined constant NULL
represents a null or empty pointer. I’ve written before that the constant isn’t defined as zero, though such an assumption could lead you into trouble.
Keep in mind that NULL
is a defined constant. It’s declared in the stdio.h
header file or, more likely, its definition is made in another header file that’s referenced from stdio.h
. Either way, the problem is that various C compilers can define NULL
differently.
Before diving into the details, be aware that NULL
is a pointer constant. It’s not the same as integer value zero (though it might be defined that way). NULL
is used where a pointer, a memory address, is to be evaluated or set as an argument.
Also, NULL
isn’t the same thing as the null character, \0
. This character is ASCII code zero, but it’s not a pointer. It’s a character value. (In some of my earlier books, I referred to \0
as the “NULL character,” which is incorrect.)
Finally, NULL
isn’t memory location (address) zero. It may be the value zero as it’s defined, but it’s not a memory location. Instead, think of it as an “empty” location and not zero; NULL
indicates the absence of a memory location, which is important when comparing pointers: NULL
evaluates as FALSE.
The point [sic] of this post is that despite all this NULL
nonsense, it’s unwise to assume NULL
‘s definition. From an email I recently received:
The problem with NULL is that it’s either defined as an integer zero constant or as an integer zero constant casted to a void pointer…
The assumption that NULL
is always a pointer causes problems with some functions. The takeaway here is that it’s always a good idea to typecast NULL
when you can.
For example, if a function requires a NULL
pointer as an argument, specify it like this:
function(data, (char *)NULL);
For fictitious function() above, the second argument is a char pointer. Yet, many compilers can swallow NULL
by itself as the argument, so this statement might be okay:
function(data, NULL);
But to be safe consider typecasting NULL
to the proper pointer data type, as in:
(char *)NULL
.
When the data type is unknown, use the void cast:
(void *)NULL
You may never experience an issue with NULL
on your compiler. It may be liberal enough that it understands the difference between a pointer and the integer constant zero. Still, safe coding practice is always good. Since learning about this difference, I’ve double-checked my code to ensure that NULL
s are typecast wherever possible.