[snips]
In the real world, do x86 compilers really treat more than one
representation as equal to NULL?
Yes and no. It is possible to get "short pointers" (16-bit) in different
segments (so ds
ffset, es
ffset, etc) which can be problematic, insofar
as "full" comparisons of the 32-bit values may be necessary, may fail, yet
both will happily compare to NULL (since, by default, only the offset is
considered), and which have yet another problem when being compared to an
absolute address 0 (eg segment 0, offset 0).
That said, in order to get into such a mess, you have to be doing things
beyond the scope of what C actually does.
However...
It is remotely possible to get into a slightly related situation, where
pointers are treated by default as full 32-bit integers - but because of
oddities in addressing, each machine address can be represented by
something like 16 unique segment
ffset pairs, hence 16 different integer
values.
Compilers which support this mode generally also produce normalizing code
for pointer operations such that comparing pointers can be done sensibly,
but this obviously has something of an impact on performance, so if you
need to work in modes such as this, the norm is to disable the
normalization for pointers involved in performance-sensitive areas and
normalize yourself when and as needed, rather than continuously.
Again, if you need to know this, you're well into non-standard-C-land, so
it's not really much of an issue - but it can potentially cause problems if
a library isn't expecting normalized pointers and thus doesn't do the right
thing, or, conversely, is expecting them but not getting them.
The short answer to the question, though, at least as far as conforming C
code is concerned, is no.