Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!husc6!hao!noao!arizona!gmt From: gmt@arizona.edu (Gregg Townsend) Newsgroups: comp.lang.c Subject: What is NULL? There is no right answer! Message-ID: <1810@megaron.arizona.edu> Date: Mon, 13-Jul-87 14:08:42 EDT Article-I.D.: megaron.1810 Posted: Mon Jul 13 14:08:42 1987 Date-Received: Wed, 15-Jul-87 02:05:32 EDT Organization: U of Arizona CS Dept, Tucson Lines: 62 Keywords: NULL 0 pointer C Confusion about the *concept* of NULL seems to be causing most of the problems. Some credible definitions are: 1. NULL is simply shorthand for 0 and is used only for readability. 2. NULL is a zero pointer of type (char *), and as such NULL is a legal parameter to a function expecting a (char *) argument. 3. NULL is a zero pointer of the universal pointer type used by malloc() etc., which just happens to be (char *). I can't find any historical definition that I consider authoritative. Kernighan & Ritchie use a privately defined NULL on page 97 but it's not clear that we should consider that any more universal than ALLOCSIZE defined the line below. The index entry for NULL also points to a page containing a discussion of 0 as a pointer value, and using the lower-case adjective "null", but that's pretty tenuous to be considered a definition. The value of NULL that most of us use comes from. The v7 man page for stdio(3S) defines stdin, stdout, and stderr (which are FILE *) and then says "A constant `pointer' NULL (0) designates no stream at all." This sounds like a narrow definition as a (FILE *), but then the man pages for gets() and others reference NULL in a (char *) context. In newer references, Kernighan and Pike (p.177) say NULL is "usually" defined as (char *)0, while talking about the return from (FILE *) fopen(). Harbison and Steele (p.94) say it's usually defined as 0. In the absence of a clear and visible definition, it's no wonder people have built up concepts based on observed usage. With many (most?) C compilers, programs assuming ANY of the above concepts run just fine with NULL defined as 0 in . With 16-bit ints and 32-bit longs and pointers, a definition of 0L keeps all the concepts viable. But when pointers get bigger than longs, or different pointers have different sizes, a definition satisfying all assumptions becomes difficult or impossible. After writing the above paragraphs without prejudice I planned to look at the proposed ANSI standard [Oct 86]. After all, they've presumably spent a lot more time wrestling with this problem than most of us. And now what do I find? (p. 85) NULL [...] expands to an implementation-defined null pointer constant; (p. 30) An integral constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. So allowing for the new form of a universal pointer, they've allowed both #1 and #3, implementation dependent. Because (void *) 0 can be compared to any other pointer without error, if you code assuming definition 1 you're always safe. The rationale (Sep 86, p. 65) adds: [definition of NULL as (void *)0] is necessary on architectures where the pointer size(s) do(es) not equal the size of any integer type. This seems to imply that NULL must always work as an argument to a (void *) parameter (concept #3), but the rationale isn't the standard. No wonder everyone's confused. I learned something just researching this message. There is no authoritative, correct answer. Even the proposed new standard is ambivalent. Gregg Townsend / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 4325 gmt@Arizona.EDU 110 57 17 W / 32 13 47 N / +758m