Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!pasteur!ucbvax!ucsd!ucsdhub!esosun!seismo!uunet!steinmetz!davidsen From: davidsen@steinmetz.ge.com (William E. Davidsen Jr) Newsgroups: comp.lang.c Subject: Re: Let's define our own NULL Message-ID: <11388@steinmetz.ge.com> Date: 27 Jun 88 15:13:27 GMT References: <11326@steinmetz.ge.com> <1090@holos0.UUCP> Reply-To: davidsen@crdos1.UUCP (bill davidsen) Organization: General Electric CRD, Schenectady, NY Lines: 71 In article <1090@holos0.UUCP> lbr@holos0.UUCP (Len Reed) writes: | > argument lists terminating with NULL, since *only* assignment will | ^^^^^^^^^^^^^^^^ | What about initialization? Surely this works: | char far * cfptr = 0; | | > translate zero to a pointer. Look at the exec family to see where NULL | > is passed where a pointer is expected. Well, I might have used the the "assignment operator," but I think you see what I mean. | On the PC family I'm using Microsoft 5.x and SCO Xenix. I use | function prototypes with typed arguments; I don't see why "0" won't work | in all cases. The compilers cast "0" to the proper (far or near) null | value. Do you have an example using function prototypes with type, | information, where this would fail? Is there a compiler that allows | ((void *)0) but not prototypes? I tried both SunOD and Ultrix. Both barfed at the prototype. I don't have access to a "real BSD" compiler, but I think this might be typical of BSD. The point in case was execl, variable number of args, type char *. What do you use for the prototype of that, and if VOID is zero, does it generate a far pointer when you end a list with NULL in large model? | Even ((void *)0) won't get you out of all mixed-mode pointer problems. I totally agree. What I was saying was that it generally *will* get you out of constant mode problems. | I like the idea of | #define NULL ((void *)0) | though, since much imported code won't use function prototypes. | Also, ((void *)0 will provide better type checking than 0. My compilers | will complain if I use a (void *) where something other than a pointer is | expected, but they allow 0 to be used (almost?) anywhere. A benefit I hadn't considered. | Some folks use NULL when they should say '\0'; ((void *)0) can | cause a warning here. Maybe that's just as well: use 0 or '\0' for | a null character, but use NULL only for pointers. I usually define a symbol, (EOS for end of string) which is '\0'. A good point, anything which gives the compiler a better chance to catch errors is a win. | Microsoft C 5.1 stdio.h defines NULL as 0 or 0L depending upon the model. | This can cause spurious loss of precision warning messages when using | explicit "near" pointers in the large model, and is thus inferior | to ((void *)0). | | All said, I like ((void *)0) and may adopt it. One additional | philosophical reason to use it. (void *) means generic pointer, and | thus ((void *)0) means generic pointer with value zero, which is | surely closer to "null pointer" than 0. | | -- | - Len Reed Although I expected flames, almost all of the responses were technical in nature, and well thought out, such as this one. I did get a few nastygrams, but they were mainly in the nature of "we are tired of discussing NULL," rather than disagreement. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me