[comp.lang.c] I'm confused

chu@acsu.buffalo.edu (john c chu) (07/17/90)

In article <9007161750.AA00664@edison.CHO.GE.COM> rja <rja@edison.cho.ge.com> writes:
>I used to use a compiler for MSDOS and the 80x86 cpus 
>whose NULL pointer was F000:0000 hex when examined via
>a debugger.  It of course did compile fine as long as one
>used sense and compared pointers to NULL rather than 
>a constant of zero...

I thought NULL was a macro defined to be 0 or (void *)0
so that it didn't matter what the computer itself uses for a "null"
pointer, C would always use 0 and making it whatever it's suppose to
be to fit the computer was the compiler's job.

Anyway, I thought comparing a pointer to NULL was the same as
comparing a pointer to (a properly cast) zero.

Am I way off base?

					john
				chu@autarch.acsu.buffalo.edu

(When is the next time the FAQ list gets posted? I have a feeling most
of my questions are probably answered there.)

karl@haddock.ima.isc.com (Karl Heuer) (07/17/90)

In article <30820@eerie.acsu.Buffalo.EDU> chu@acsu.buffalo.edu (john c chu) writes:
>In article <9007161750.AA00664@edison.CHO.GE.COM> rja <rja@edison.cho.ge.com> writes:
>>[On a machine where the internal representation of a null pointer wasn't 0]
>>It of course did compile fine as long as one used sense and compared
>>pointers to NULL rather than a constant of zero...

If it was compiling C, then it should have worked without that clause.

>I thought comparing a pointer to NULL was the same as comparing a pointer to
>(a properly cast) zero.

In a pointer context, NULL and properly-cast 0 and naked 0 are all equivalent:
each refers to the null pointer of the type implied by the context.

As an argument to a function not covered by a prototype (this being the only
place you can put a null pointer constant and not have a pointer context), a
properly-cast NULL and a properly-cast 0 are equivalent.  Naked 0 and naked
NULL are both incorrect if a null pointer was desired.

>I have a feeling most of my questions are probably answered [in the FAQ]

Yes, they are.

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint

rja@edison.cho.ge.com (rja) (07/20/90)

Actually, I don't think I worded my posting clearly.

It is true without doubt that both K&R and ANS X3.159 C
both guarantee that comparing a pointer to "0" is the
same as comparing a pointer to "NULL."  

It is also something that is broken on several widely
used C compilers for the Intel segmented architecture.

At least one such compiler doesn't "#define NULL 0" or
even "#define NULL (void *)0" and will compare the offset
of the pointer to the offset of the NULL pointer address
rather than comparing the whole pointer to the whole NULL
pointer address.  In short, yes everyone agrees that such
compilers are broken but they are in common use and so
experience has taught some of us to always compare to NULL
rather than 0 because it is more portable to the several
broken compilers for the Intel architecture.  Ideally, one
can simply choose to avoid such compilers, but it isn't always
practical for non-technical reasons...

scs@adam.mit.edu (Steve Summit) (07/23/90)

In article <9007201132.AA06954@edison.CHO.GE.COM> rja <rja@edison.cho.ge.com> writes:
>It is true without doubt that both K&R and ANS X3.159 C
>both guarantee that comparing a pointer to "0" is the
>same as comparing a pointer to "NULL."  
>It is also something that is broken on several widely
>used C compilers for the Intel segmented architecture.

It wouldn't hurt if you named names.  The existence of such
broken compilers is one of the reasons that null pointer
confusion never ends.  A compiler that doesn't properly treat "0"
as a source-code null pointer is truly broken, and its vendor
couldn't complain about libel or slander if that fact were
mentioned here.  (If the compiler in question is in fact not
broken, or if it has been fixed in a later version, it would be
nice to get the word out to those who had believed it was broken
so they can stop being duplicitous about NULL, either.)

                                            Steve Summit
                                            scs@adam.mit.edu

chip@tct.uucp (Chip Salzenberg) (07/27/90)

According to scs@adam.mit.edu (Steve Summit):
>rja <rja@edison.cho.ge.com> writes:
>>[NULL] is broken on several widely
>>used C compilers for the Intel segmented architecture.
>
>It wouldn't hurt if you named names.

I think he's talking about Turbo C and Microsoft C, which of course
are not broken (with respect to NULL, anyway).

In a portable program, any pointer may be compared for EQUALITY with
NULL.  Microsoft and Borland handle this case correctly.

However, in a portable program, no pointer may be compared for
RELATIVE MAGNITUDE with NULL.  Attempting to do so under Microsoft or
Turbo C will result in a comparison of the segment offset, but not the
segment selector.

Why is this done?  Efficiency.  Is it broken?  No.  Read on...

The ANSI C standard does not guarantee that comparisons of magnitude
with NULL will do anything meaningful.  Comparisons of magnitude are
only valid within a single object (structure or array), and by
definition, NULL cannot point to any object.

By coincidence, comparisons of magnitude with NULL work on many
architectures.  The '286 isn't one of them.
-- 
Chip Salzenberg at ComDev/TCT     <chip@tct.uucp>, <uunet!ateng!tct!chip>