As you know, in standard modern C language the constant 0 value used in pointer context acts as a null-pointer constant, which gets converted to a platform-specific (and possibly even type-specific) null-pointer value.
Meanwhile, the early versions of C language, as the one described in C Reference Manual, did not make much of a distinction between pointer and integer contexts, allowing one to freely compare and assign integers to pointers. If am not mistaken, in that version of C the constant 0 had no special status, meaning that assigning the value of constant 0 to a pointer would simply make it point to physical address 0 (just like assigning the value of 42 to a pointer would make it point to physical address 42).
In ANSI C things have changed significantly. Now assigning the constant 0 to a pointer will place some platform-specific null-pointer value into that pointer. Null-pointer value is not required to be represented by physical 0 value.
So, at what point in the history of C language did it change from one to another? Did K&R C already incorporate the higher-level concept of null-pointer with constant 0 given its special status? Or did the K&R C still guarantee physical assignment of integers to pointers even for constant 0?
It's not even an address abstraction, it's the constant specified by the C standard and the compiler can translate it to some other number as long as it makes sure it never equals a "real" address, and equals other null pointers if 0 is not the best value to use for the platform.
A null pointer constant is an integer constant expression that evaluates to zero. For example, a null pointer constant can be 0, 0L , or such an expression that can be cast to type (void *)0 .
A null pointer is a pointer which points nothing. Some uses of the null pointer are: a) To initialize a pointer variable when that pointer variable isn't assigned any valid memory address yet. b) To pass a null pointer to a function argument when we don't want to pass any valid memory address.
A null pointer stores a defined value, but one that is defined by the environment to not be a valid address for any member or object.
It goes back to nearly the beginning of C (if not the very beginning). If you look on page 21 of the January 1974 C reference manual, it's more or less directly stated in some sample code:
/* is pointer null? */
if (p == 0) {
Going back still a bit further, to ca. 1972-73 PDP-11/20 compiler, we find:
match(tree, table, nreg)
int tree[], table[]; {
extern opdope[], dcalc, notcompat;
int op, d1, d2, t1, t2, p1[], p2[];
char mp[];
if (tree==0)
return(0);
op = *tree;
At least if I'm reading this correctly, the if (tree==0)
line is checking that tree
is a non-null pointer before attempting to dereference it.
Unfortunately, Dennis says he can't be much more certain about the date than "1972-73".
There isn't much history of C before that. Nonetheless, there does seem to be a bit of history of 0 being treated as a null pointer. It looks to me like use of 0 as a null pointer is something that C "inherited" from Unix. The entry for exec
in the November 1971 1st Edition Unix programmer's manual shows a pointer with the value 0 to signal the end of the list of arguments. According to Dennis' description, at this point "C was still to come."
Based on all this, I'd tentatively conclude that C treated 0 as a null pointer from the very beginning, or at least so early on that there's probably no longer any record of a version of the language that was otherwise.
I haven't been nearly as successful at tracking down documentation about the first point at which a null pointer might have had non-zero bits. From the viewpoint of the language, this has never been relevant. I suspect it happened fairly early on, but finding documentation to support that would be difficult. One of the earliest ports of C was to IBM System/360 mainframes, and although I can't find direct documentation of it, my guess would be that internally the null pointer value used on these machines was probably non-zero. I don't have the exact number handy, but I know that PL/I on these machines used a non-zero value for its equivalent of a null pointer; I'd guess that when they ported C to these machines, they probably used the same value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With