I'm not too hung up on it, but I guess it sticks in my craw just a bit
that this goes against the so-called spirit of C. I just wonder why
this particular check is handled automatically, while all other
runtime error checking that I can think of is left up to the
programmer to implement.
Interesting question!
Here's my thought: When I ask the library to strcpy, printf, or otherwise
USE a null pointer, I am implicitly referring to the thing-pointed-to. Unlike
these, "free()" really doesn't implicitly refer to the thing pointed to, only
to the pointer. (In practice, that may well imply referring to, say, space
just before the thing pointed to... But that's an internal detail.)
So there's a conceptual difference there. free() is only talking about the
pointer, not using it. It is easy to specify what to do for free(NULL) --
obviously, you don't want to do anything, because there's already no allocated
object there, and it is guaranteed trivial to determine this to be the case.
Contrast with:
free(invalid_ptr);
There is no obvious cost-effective way for the implementation to
determine that you've tried to free an invalid pointer, in the general
case, so it's not clear that it's reasonable to expect this to work.
strcpy(buffer, NULL);
What should this do? It can't just copy "until it reaches the \0",
nor can we guess whether you want this to copy zero bytes, or just
silently append a '\0', or what.
sprintf("%s", NULL);
Again, what should this do? Do you want no output? Something like
the string "(null)"? "<nil>"? The contents of memory location zero
up through the first '\0'?
But free(NULL) is both unambiguous and cheap to detect.
Similarly, you're probably more likely to encounter a variety of cases where
a pointer is either-null-or-allocated.
Finally, last but not least:
void *v;
v = malloc(N);
free(v);
This should work, because you should be able to free something that was just
returned by malloc.
-s