More crap about nil (was Is "if (!pointer)" ...)
Chris Torek
chris at mimsy.umd.edu
Wed May 2 19:30:27 AEST 1990
> "The name of the null pointer is called 'NULL'"
>
>... but that's only what the name is called, you know.
>The name really IS "0". But that's only the name, not a representation.
>--
>Wayne Throop <backbone>!mcnc!rti!sheol!throopw or sheol!throopw at rti.rti.org
Right. There are three separate issues; people generally insist on
tying all three into one (so they have to be handled together).
A. The (runtime) representation for `the' nil pointer.
This issue is particularly sticky. As a programmer writing
portable C, you (a) have no idea what the representation is and
(b) have no idea whether there is only one representation.
There can be---and on some machines, the most `natural' setup
has---several different `nil's, such as a `nil pointer that
points to bytes' versus a `nil pointer that points to words',
or---as on an IBM PC in certain models---a `nil pointer that
points to data' versus a `nil pointer that points to code'.
All of these `nil's are different, at least in principle if
not often in fact. In some cases the difference cannot be
swept under the rug. The mixed-model IBM PC example is one
of the best. There is no way the compiler can cheat with
#define NULL 0
or
#define NULL 0L
that will hide the fact that a nil data pointer and a nil code
pointer have different sizes in a mixed-model-memory-mode.
Fortunately, it Just So Happens that, while you have no idea
what representation(s) the nil pointer(s) has/have, you do
not need to know.
B. The (compile-time) syntax for the nil pointer.
In Classic C, there was only one syntax for a nil pointer.
One wrote up an expression such that the compiler could tell
`I mean for this to be a pointer', then wrote the constant
`0'. In New C, there are two: one writes up an expression
as before, then writes either `0' or `(void *)0'.
Other languages are more clever about this: they have a keyword
(`nil') that tells the compiler `I want a nil'. If C had such
a keyword, one could use it in all situations and let the
compiler complain when one accidentally left out the context
telling it what *particular kind* of nil pointer one wants (see
point A above). Unfortunately, C is not clever this way; if a
programmer leaves out the context, the compiler has to assume
that the programmer meant `the integer zero' or `a nil pointer
of type pointer-to-void'. If you want to make sure you never
accidentally leave out the context, there are two very simple
ways to do this.
Way 1: always use a cast. (This is overkill.)
Way 2: always use a cast in every function call. (In Old C,
this is never overkill and is always required. In New C, this
is overkill when a function prototype supplies the pointer
context. Not all prototypes do so, and the cast never hurts.)
C. The word used for the syntax (when humans read and write C code).
K&R (both editions), and many programming styles, recommend
that programmers write `NULL' when they mean `I think I have
supplied context for the compiler, and I want a nil pointer of
the particular kind specified by this context'. This helps the
human reading the code tell that (a) you think you supplied a
pointer context (whether you did or not) and (b) that you
wanted a nil pointer of some kind. A competent C programmer
should be able to tell whether there is in fact sufficient
context for the compiler, and any C programmer should be able
to tell that you meant `a nil pointer of some kind'. The
competent maintenance programmer can then find the context, see
what kind of nil is going to get used, and decide whether this
is the right thing to do. (The same competent maintenance
programmer might find instead that the context is missing,
which might well be the source of the bug that sent said
maintenance programmer off to look at the code in the first
place.)
You can, of course, use the compile-time syntax for the nil
pointer (i.e., `0') instead of NULL---after all, you *did*
provide the context the compiler needs (you did, right? ... are
you *sure*?). The danger in doing this is that even a
competent maintenance programmer can then miss the fact that
this is supposed to be a nil pointer, not really a zero; this
can lead the maintenance programmer astray, and your name may
become infamous.
So, to sum up:
- The name of the nil pointer is called NULL.
- But that is just what the name is called. The name itself is `0'.
- But that is just the name. The nil pointer itself is something
else entirely, if indeed there is only one nil pointer. If you
want to write a compiler, you will need to know what the nil pointer
really is; but if you just want to write C programs, you can make
do with the name of the nil pointer, and with what the name is called.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list