> Oh -- actually, that's why I made that change (plus a much larger
> one right after it). One can't reliably assume that pointer fields
> in the new structure will be NULL after this? If not, I'll need to
> change a few places in the code... Can you elaborate? Thanks.
Basically, when the C compiler sees a constant "0" used in a pointer
context (via explicit or implicit cast), it will convert it to the
null pointer. But there is no guarantee in ANSI C that the null
pointer is represented by all zero bytes internally.]
An interesting bit of lore resulting from this and other aspects of C
is that if you're invoking a variable-arguments function like execl(),
you cannot pass an uncasted NULL or 0 as one of the variable
arguments, because the compiler does not know that the argument is a
pointer or what type of pointer it is. So you have to write something
like:
execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
to be correct. "(char *) 0" at the end would be just as correct, of
course.
Of course, in reality, almost every C implementation uses
all-zero-bytes to represent the null pointer, because too much code
would break if they didn't.
See http://www.faqs.org/faqs/C-faq/faq/ section 5 for more
information. In particular, from question 5.14:
One good way to wade out of the confusion is to imagine that C
used a keyword (perhaps "nil", like Pascal) as a null pointer
constant. The compiler could either turn "nil" into the
appropriate type of null pointer when it could unambiguously
determine that type from the source code, or complain when it
could not. Now in fact, in C the keyword for a null pointer
constant is not "nil" but "0", which works almost as well,
except that an uncast "0" in a non-pointer context generates an
integer zero instead of an error message, and if that uncast 0
was supposed to be a null pointer constant, the code may not
work.
Question 5.17 enumerates some platforms which don't use all-zero-bytes
to represent the null pointer, just so you can see the (limited)
extent of the practical effect.
Purely as a matter of style, I prefer not to use calloc() or memzero()
even to zero out integral types. I think it's a bug if a field wasn't
initialized before use, and masking such bugs with zero-filling does a
disservice to the program's maintainability. But I'm not going to be
religious about such style issues.
Received on Sat Oct 21 14:36:10 2006