Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site mordor.UUCP Path: utzoo!watmath!clyde!burl!ulysses!ucbvax!ucdavis!lll-crg!mordor!jdb From: jdb@mordor.UUCP (John Bruner) Newsgroups: net.lang.c Subject: Re: if(p) Message-ID: <4173@mordor.UUCP> Date: Fri, 1-Nov-85 16:29:42 EST Article-I.D.: mordor.4173 Posted: Fri Nov 1 16:29:42 1985 Date-Received: Sun, 3-Nov-85 09:38:07 EST References: <1671@brl-tgr.UUCP> <30000017@ISM780.UUCP> Reply-To: jdb@mordor.UUCP (John Bruner) Organization: S-1 Project, LLNL Lines: 58 In article <366@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes: >Um, treating an all-0 value as a pointer? But what operation do you do on >pointers apart from dereferencing that could be construed as doing something >with a *pointer* as opposed to doing something with a *variable*? Sounds like >some net.bizarre sort of tagged architecture, in which case you can throw >portability out the window anyway. I mean, what would this do to implicit type >conversion, just for starters? OK, let's rephrase that. What sort of >architecture could you actually implement 'C' on, and reasonably easily port >programs to and from, that wouldn't let you use 0 as a pointer? A few months ago I described the problems that the incorrect assumption that (foo *)0 has an all-zero-bits representation caused when we were attempting to transport C programs to our machine, the S-1 Mark IIA. The Mark IIA has a 36-bit word. Pointers are partitioned into a 5-bit tag and a 31-bit address. The different tag values specify different protection rings (ring 0 == kernel, ring 3 == user) and special pointer types (nil, self-relative). [We did not use self-relative pointers in C.] The tag values 0 and 31 are reserved as invalid. Any attempt to manipulate a pointer with an invalid tag causes a trap. Since most integers will be either small negative or positive numbers, this helps to detect the use of uninitialized pointers. Just as floating-point numbers are manipulated differently than integers, there are instructions to copy and manipulate pointers. An attempt to copy an all-zero word with a pointer instruction causes a trap. Pointers with the "nil" tag can be copied, but they cannot be used in address expressions. Of course, "nil" cannot be de-referenced. Pointer to integer coercions are possible (just as conversions between floating-point and integers are possible). However, K&R does not guarantee that all integers can be copied into a pointer. It only guarantees that (given sufficiently large integers, conversion from pointer to integer to pointer will return the original pointer. In particular, it is *not* guaranteed that you can always do something like this: p = (char *)10; After fighting the tide of sloppy coding practices, we finally gave in and changed the meaning of tag 0 (in microcode) and adopted an all-0 bit pattern for NULL. It was wrong, it was ugly, but it was the only expedient thing to do. If C is to survive as a language it must be allowed to escape its PDP-11 origins (and I include the VAX [and to some degree the 68000] in this category). (foo *)0 is not an all-zero bit pattern; it may not even be a memory address. Although this may be the implementation on some (or even most) machines, the abstract idea should not be confused with the most common implementation. -- John Bruner (S-1 Project, Lawrence Livermore National Laboratory) MILNET: jdb@mordor [jdb@s1-c.ARPA] (415) 422-0758 UUCP: ...!ucbvax!dual!mordor!jdb ...!seismo!mordor!jdb