NULL isn't 0/0 isn't NULL
Author Message
NULL isn't 0/0 isn't NULL

Oh how soon they forget.

All you people worrying about NULL not being the same bit pattern as 0
have forgotten that it is not required that 0 have the same bit pattern
as 0x0000....   Consider sign-magnitude arithmetic with the possibility of
-0 being different from +0.  I can think of more bizarre yet reasonable
representations of 0, but I don't know if they have ever been implemented.

(Not that this is germane to the fact that 0 === NULL.)
(By === I mean "is guaranteed to be equal to")

Zed Smith

(Not my employers opinions.)

Thu, 08 Oct 1992 03:37:30 GMT
NULL isn't 0/0 isn't NULL

Quote:

>All you people worrying about NULL not being the same bit pattern as 0
>have forgotten that it is not required that 0 have the same bit pattern
>as 0x0000....

ANSI C does pretty much require a straight binary representation, actually,
although there are some weasel-words on the subject of negative numbers
that should permit a variety of representations for things with minus signs
on the front.
--
If OSI is the answer, what on |     Henry Spencer at U of Toronto Zoology

Thu, 08 Oct 1992 09:49:02 GMT
NULL isn't 0/0 isn't NULL

Quote:

>All you people worrying about [other beaten horse that will never die]
>have forgotten that it is not required that 0 have the same bit pattern
>as 0x0000....

Essentially false.  0x0000... is not a bit pattern.  0x0000... is an
integer constant, exactly the same as 0.  Both of them turn into bits
in exactly the same way.

(Irrelevant digression:  this also means that (void *)0x0 is a
null pointer, ANSI-conformant and ANSI-portable.)

Quote:
>Consider sign-magnitude arithmetic with the possibility of
>-0 being different from +0.

Well, this topic has been discussed before, and I don't recall the
resolution.  Does 0 always have the same bit pattern as another 0?
I can't find the relevant section in the standard.

But how do you tell if two zeroes are different, let's see...
if (0 == 0)              must always be true.
if ((unsigned) 0 == 0)   must always be true.
if ((0 | 0) == 0)        hmmm, this must always be true too.
if ((0 >> 1) == 0)       all right, maybe we have a CHANCE.  But of course,
you can't expect consistent results out of this,
either true or false (except for a true if some
ANSI section requires it).  If you ask hard enough
for inconsistency, you should expect to get it.

--

This_blank_intentionally_left_underlined________________________________________

Fri, 09 Oct 1992 08:44:17 GMT
NULL isn't 0/0 isn't NULL

Quote:
>But how do you tell if two zeroes are different?...

In what follows, whenever I say "0", I mean the bit pattern of all zeros,
not the local implementation's idea of a pointer to nothing.  When I mean a
pointer to nothing, I will say "NULL".

Try running the program shown to see if NULL==0 on your machine.
There has been much discussion lately about whether or not NULL==0 is
required by ANSI.  To me, the whole issue seems moot, since I know of
no machine where this is not the case.  If anyone does know of a
computer for which NULL!=0, then I would appreciate hearing from them.

main()
{
char *x[4];
long int i;

x[0] = x[1] = x[2] = x[3] = 0;   /* extra NULLs in case
sizeof(long)>sizeof(char*) */
i = *(int *)&(x[0]);             /* Copy bit pattern in x[0] into i */
if( i==0 ){
printf("NULL is a binary 0 on this machine.\n");
}else{
printf("NULL is NOT a binary 0 on this machine.\n");
}

Quote:
}

Fri, 09 Oct 1992 22:46:05 GMT
NULL isn't 0/0 isn't NULL
[Followups directed to comp.std.c]

Quote:

>>have forgotten that it is not required that 0 have the same bit pattern
>ANSI C does pretty much require a straight binary representation, actually,

Doesn't the "as-if rule" come into play, though?  Couldn't I have a BCD
implementation, so long as I make sure of things like (5 << 2 == 20) ?  I
admit that given things like bit fields and bit-shift operators it would be
pretty painful to use a BCD implementation, but I'm talking about
legalities, not quality of implementation.
--
Barry Margolin, Thinking Machines Corp.

{uunet,harvard}!think!barmar

Fri, 09 Oct 1992 11:22:04 GMT
NULL isn't 0/0 isn't NULL

Quote:

>>But how do you tell if two zeroes are different?...

>In what follows, whenever I say "0", I mean the bit pattern of all zeros,
>not the local implementation's idea of a pointer to nothing.  When I mean a
>pointer to nothing, I will say "NULL".

>Try running the program shown to see if NULL==0 on your machine.

Well, I did and it was... :=)

An interesting note, however, Microsoft C in the OS/2 SDK treats NULL and
0 as the same thing. It would seem to me that this is wrong (at least according
to K&R 1st Edition) since a "pointer" is being treated as an integer. In all the
different hardware environemnts I have worked with (Z80, 80x86, VAX, System/370,DEC PDP 10, 11 and DEC System 20) a NULL pointer has an empty bit pattern.

Food for thought, and I got the munchie! :)

********************************************************************************

408/241-1533 Process Scientific, Inc.
--------------------------------------------------------------------------------
"0x2B|~0x2B THAT is the question!"
********************************************************************************
DISCLAIMER: #include <std.disclaimer>
Flames, Grammar, and SPELLING errors etc: >/dev/null
--------------------------------------------------------------------------------

Sun, 11 Oct 1992 06:28:24 GMT
NULL isn't 0/0 isn't NULL

Quote:
>The HP 300  (known as the Amigo) used  -1  as NULL, because

The HP300 is NOT the HP9000/300

jim miller

Sun, 11 Oct 1992 07:30:43 GMT
NULL isn't 0/0 isn't NULL
Ah, jeez.  Just use NULL or 0, whichever you prefer, and leave it, okay?
We're past that point of fractional angels on pinheads...

Sun, 11 Oct 1992 00:51:12 GMT
NULL isn't 0/0 isn't NULL

Quote:
Hipp) writes:

> >But how do you tell if two zeroes are different?...

> In what follows, whenever I say "0", I mean the bit pattern of all zeros,
> not the local implementation's idea of a pointer to nothing.  When I mean a
> pointer to nothing, I will say "NULL".

> Try running the program shown to see if NULL==0 on your machine.
> There has been much discussion lately about whether or not NULL==0 is
> required by ANSI.  To me, the whole issue seems moot, since I know of
> no machine where this is not the case.  If anyone does know of a
> computer for which NULL!=0, then I would appreciate hearing from them.

> main()
> {
>    char *x[4];
>    long int i;

>    x[0] = x[1] = x[2] = x[3] = 0;   /* extra NULLs in case
>                                          sizeof(long)>sizeof(char*) */
>    i = *(int *)&(x[0]);             /* Copy bit pattern in x[0] into i */
>    if( i==0 ){
>       printf("NULL is a binary 0 on this machine.\n");
>    }else{
>       printf("NULL is NOT a binary 0 on this machine.\n");
>    }
> }

The HP 300  (known as the Amigo) used  -1  as NULL, because
it was an illegal address, whereas  0  was a perfectly good address;
indeed, one could modify the machine to push -1's on the stack
as a way of catching references through un-assigned pointers.

There are a couple of 300's out there, still.  On the other hand
they did not have a C compiler.

My guess is that any architecture that does not have a linear
address space would be a possible candidate.

Sun, 11 Oct 1992 00:30:59 GMT
NULL isn't 0/0 isn't NULL

Quote:
> To me, the whole issue seems moot, since I know of
> no machine where this is not the case.  If anyone does know of a
> computer for which NULL!=0, then I would appreciate hearing from them.

Prime.
The machine repn of NULL is (07777<<17).  Weird, huh?
Dereferencing a pointer of this value will result in a null pointer exception,
but dereferencing a pointer of all bits zero
will result in an unmapped segment exception.

The "I never heard of one" argument pops up often in this newsgroup.
If you catch yourself doing this, castigate yourself severely.

Regards
Peter Miller       UUCP    {uunet,mcvax,ukc}!munnari!neccan.oz!pmiller

Disclaimer?  These guys have no idea what I am on about!
D

Wed, 14 Oct 1992 00:29:42 GMT
NULL isn't 0/0 isn't NULL
<< If anyone does know of a
<< computer for which NULL!=0, then I would appreciate hearing from them.
<Prime. The machine repn of NULL is (07777<<17).  Weird, huh?
<Dereferencing a pointer of this value will result in a null pointer exception,
<but dereferencing a pointer of all bits zero
<will result in an unmapped segment exception.
<The "I never heard of one" argument pops up often in this newsgroup.
<If you catch yourself doing this, castigate yourself severely.

I asked this question on the net about 0!=NULL and 0!=0.0. The results were:
1. NO machines with 0.0!=0.
2. Prime had NULL!=0, but, as you pointed out above, the C compiler still
could have NULL be a 0 bit pattern. No problem here.
3. The CDC {*filter*} 180 series has NULL!=0. I'm not convinced either that
case 2 doesn't apply here.

Conclusion: Unless you wish to port to some old obsolete {*filter*}, don't worry

I think ANSI C did the community a disservice by not coming out and saying
NULL==0 and 0.0==0. What they did generates more confusion and complexity
than the infamous array<==>pointer problems.

Remember that a NULL pointer doesn't necessarilly have to cause exceptions
when dereferenced. It only needs to be a unique value, that malloc() and
friends do not return, and that &variable is never NULL.

Sat, 17 Oct 1992 02:46:03 GMT
NULL isn't 0/0 isn't NULL

Quote:

>Prime.

Of course, if you want your software to run on as many machines as
possible, you should consider Prime.

On the other hand, if you want as much software as possible to run
on your machine, you certainly shouldn't consider Prime.

-- Richard
--

Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

Sat, 17 Oct 1992 00:55:30 GMT
NULL isn't 0/0 isn't NULL

Quote:

>I asked this question on the net about 0!=NULL and 0!=0.0. The results were:
>1. NO machines with 0.0!=0.
>2. Prime had NULL!=0, but, as you pointed out above, the C compiler still
>   could have NULL be a 0 bit pattern. No problem here.
>3. The CDC {*filter*} 180 series has NULL!=0. I'm not convinced either that
>   case 2 doesn't apply here.

Honeywell DPS-8 has a non-zero representation for 0.0. The multi-segment
mode null pointer might not be 0 either (I'm not sure). I suspect that
there are several mainframes that don't use 0 bit patterns for these,
but there probably aren't too many users of them on a primarily Unix
network.

David Tanguay

Sat, 17 Oct 1992 18:24:22 GMT
NULL isn't 0/0 isn't NULL

Quote:
>An interesting note, however, Microsoft C in the OS/2 SDK treats NULL and
>0 as the same thing. It would seem to me that this is wrong (at least according
>to K&R 1st Edition) since a "pointer" is being treated as an integer. In all the
>different hardware environemnts I have worked with (Z80, 80x86, VAX, System/370,DEC PDP 10, 11 and DEC System 20) a NULL pointer has an empty bit

K&R2 p 102:
Pointers and integers are not interchangeable.  Zero it the sole
exception: the constant zero may be assigned to a pointer, and a pointer
may be compared with the constant zeto.  The symbolic constant NULL is
often used in place of of zero ...  NULL is defined in <stdio.h>. We
will use NULL henceforth.

nuff said?

jim - RTFM - miller

Sat, 17 Oct 1992 01:23:30 GMT
NULL isn't 0/0 isn't NULL

Quote:

>> To me, the whole issue seems moot, since I know of
>> no machine where this is not the case.  If anyone does know of a
>> computer for which NULL!=0, then I would appreciate hearing from them.
>Prime.
>The machine repn of NULL is (07777<<17).  Weird, huh?
>Dereferencing a pointer of this value will result in a null pointer exception,
>but dereferencing a pointer of all bits zero
>will result in an unmapped segment exception.

I believe that the question concerned the *notation* for NULL. On a Prime, the
notation for NULL (cast to an integer) is 0. You're almost right concerning the
representation of NULL for *older* Prime machines. Things on *older* Prime
machines are actually *worse* than that (as far as code portability is concerned)
The Prime architecture has multics and PL/1 as it's origins. It is a halfword
segments of 2^16 halfwords each. The Prime operating system (PRIMOS) uses the
first 4 segments for mapped I/O (i.e. a *memory reference* to address 0, is a
reference to a restricted address and results in an access violation - since
you're not supposed to dereference a NULL pointer (whatever its true value is),
this is not a problem). PRIMOS also interprets references to the last segment
(i.e. 2^12 - 1) as NULL pointers (for PL/1). That means *PL/1* null pointers
have a representation of (07777<<16). The old V/I mode C compiler shares this.
The halfword addressing served to make things worse. V/I mode pointers are
variable length (either 32 or 48 bits) as follows:

FRRESSSSSSSSSSSS
WWWWWWWWWWWWWWWW
BBBB------------

F = Fault (cause a pointer fault - used for dynamic linking)
RR = 2 bit ring #
E = Extension bit (signals that the 3 halfword is present and valid)
SSSSSSSSSSSS = segment #
WWWWWWWWWWWWWWWW = halfword #
BBBB = bit number
------------ = not used

To be fair, remember that the Prime architecture was designed (1) in 1973, and
(2) to be compatible with Honeywell (where most of the Prime founders came from).
By the mid 1980s, it was becoming painfully clear that the variable length V/I
mode pointers were not the right way to deal with things (at least as far as C
was concerned). Enter C pointers.

The observation was made that for C, a byte pointer turned on the E bit to
indicate that the 3rd halfword should be examined. If the MSB was on, address
the odd byte, otherwise address the even byte. The other "bit number" bits were
ignored. The E bit became an "indirect bit". Well... Why not just use the E bit
as the byte bit? C pointers could now fit into 32 bits (what joy!). Then a few
special instructions were added to manipulate the new pointer format:

ICP - Increment C pointer
DCP - Decrement C pointer
TCNP- Test C (NULL) pointer == 0 (ignores F and RR bits)

This led to the other thing Prime is infamous for, i.e. the LSB of the pointer
is not the "physical" LSB (the E bit is the LSB). C pointer format is:

FRRESSSSSSSSSSSSWWWWWWWWWWWWWWWW

This still causes problems for code that assumes pointers and integers look
alike (there's *alot* of this sort of code out there).This most frequently occurs
when pointers are passed to functions that manipulate them as integers *and* the
pointer is not first cast to an integer.

Anyway, all of this stuff is available in what Prime calls "IX mode" (I mode
extended). All of the machines Prime has shipped since about 1985 include IX
mode. There is also a C compiler (ci) that generates pretty good IX mode code.

In case you're wondering, I worked in the CPU group at Prime in a previous life.

-Bob

Bob Beckwith
NeXT, Inc.
900 Chesapeake Drive
Redwood City, CA 94063

Sat, 17 Oct 1992 04:42:03 GMT

 Page 1 of 2 [ 17 post ] Go to page: [1] [2]

Relevant Pages