Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mandrill!gatech!ukma!husc6!cmcl2!brl-adm!brl-smoke!gwyn
From: gwyn@brl-smoke.ARPA (Doug Gwyn )
Newsgroups: comp.lang.c
Subject: Re: NULL etc.
Message-ID: <8165@brl-smoke.ARPA>
Date: 26 Jun 88 19:50:07 GMT
References: 
Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) )
Organization: Ballistic Research Lab (BRL), APG, MD.
Lines: 30

In article  snl@cs.cmu.edu (Sean Levy) writes:
>    #define NIL(t) ((t *)0)
>    #define NULL NIL(char)

First of all, NULL must be either "0" or "((void *)0)" (the latter only
if your compiler understands void *s), so your definition is nonportable.

>    struct hostent *hp;
>    hp = gethostbyname(argv[1]);
>    if (hp == NIL(struct hostent))
>     ...

You might as well write that condition as
	if (hp == 0)
which is correct portable C.

>I would add that distinctions between 0 and a pointer become VERY
>important at a place like CMU, where code may be compiled on RT's,
>Suns, uVaxen and god knows what else.

I assume you mean the difference between an INTEGER 0 and a NULL
POINTER of a particular type (null pointers do come in types).
In many cases what looks like an integer 0 in source code actually
does represent a null pointer of the appropriate type, as in my
suggested replacement condition.  The main case where special care
is needed is when passing a pointer argument to a function.  Unless
a prototype is in scope (possible with newer C compilers only), an
argument written as just "0" will be passed as an integer, which is
a type mismatch.  Casting the 0 to the appropriate pointer type is
appropriate in such cases.