In said:
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.
The problem is that the standard allows it. For instance, if an
architecture appeared that trapped whenever an illegal address
(including 0) was loaded into an address register, then obviously
NULL would have to be some other value.
[...]
Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.
OTOH, if the CPU has dedicated address registers, it may be that ALL
pointer operations are more efficient if using address registers.
Think about a CPU with 32-bit data registers and 48-bit address registers.
On any CPU, the code generated by a C compiler has to be able to do
assignments and equality comparisons on pointer values, including null
pointer values. If loading a null pointer into an address register
causes a trap, the C implementation won't be able to use the address
registers for pointer assignment and equality comparison (unless it
can recover in the trap handler, but that's likely to be inefficient).
But there is nothing preventing the implementor to use a null pointer
representation that doesn't trap! Even if that representation is not
all bits zero.
If it's possible to perform these operations efficiently without using
the address registers, that's great;
Even then, why bother? If address registers exist in the first place,
there *must* be a reason. Not using them for pointer operation is very
likely to be inefficient, even if they have the same size as data
registers for the simple reason that data registers get under greater
pressure, while the address registers are unused. When the sizes are
different, as in my example, the difference is going to be even more
important.
a C compiler will be able to use
all-bit-zero as the null pointer value, and everything will work.
You make it sound as if there is any merit in having null pointers
represented as all bits zero. Why would the implementor try to use
that representation, if it's causing even the slightest inconvenience?
If it isn't, either the C compiler will be forced to use a different
value for null pointers,
The representation of null pointers is supposed to be the most convenient
and efficient for the implementation, so there is no reason to consider
all bits zero as an a priori solution, unless it is a convenient choice.
or it won't be possible to implement C efficiently.
Only an idiot would create an inefficient implementation for the sake of
having null pointers represented as all bits zero. See below.
The same will probably be true for languages other than
C, which probably means that no such CPU will be designed for
general-purpose computers.
Sheer nonsense. There is always an efficient solution: create a
"reserved" object at some address and use its address as the null pointer
representation. This is what most implementations are doing anyway, using
the address 0 for this purpose. But there is nothing magic about this
address, it just happens to be very convenient for this particular
purpose, on most architectures.
Since most modern machines treat addresses as unsigned integers,
address 0 happens to be at the beginning of the address space and it's
traditionally reserved anyway, on non-virtual memory architectures:
it's the address of a GPR or an interrupt vector or the entry point in
the boot loader (possibly ROM space). On virtual memory architectures,
it's simply a matter of either leaving page zero unmapped (best choice,
IMHO) or mapping but not using it (in read only mode, preferably).