Newsgroup: comp.os.minix


Article 6105 of comp.os.minix:
Path: icdoc!tsun5.doc.ic.ac.uk!zmact61
>From: zmact61@tsun5.doc.ic.ac.uk.doc.ic.ac.uk (D Spinellis)
Newsgroups: comp.os.minix
Subject: Re: NULL
Summary: NULL should be defined to be 0
Keywords: NULL 0 ANSI
Message-ID: <1347@gould.doc.ic.ac.uk>
Date: 7 Nov 89 19:52:09 GMT
References: <4455@ast.cs.vu.nl>
Sender: news@doc.ic.ac.uk
Reply-To: dds@cc.ic.ac.uk (Diomidis Spinellis)
Organization: Imperial College Department of Computing
Lines: 115
Content-Length: 4703
In article <4455@ast.cs.vu.nl> ast@cs.vu.nl (Andy Tanenbaum) writes:
>
>My inclination at the moment is to use
>
>#define NULL ( (void *) 0)
>
>If the are objections please post them, but be specific.  I am trying to do it
>right, not make it easy to use broken code.  The goal is make the
>compiler reject all incorrect programs to force people to fix them so
>they will be portable across machines with different integer and pointer
>sizes (e.g., MINIX-ST).

I will try to answer five questions in this article. (Brief answers in 
square brackets)

1. Is plain 0 a good definition fo NULL?				[yes]
2. Are there any technical problems with defining NULL as ((void *)0)?	[no]
3. Will defining NULL as ((void *)0) enable some WRONG programs to
   successfuly run on some architectures and C implementations?		[yes]
4. Will any of the two definitions of NULL make any difference on the 
   diagnostic output of the compiler in the case of wrong programs?	[no]
5. Should NULL be defined as ((void *)0)?				[no]

So in summary, both definitions are correct, none of the definitions
will change the diagnostic behaviour of the compiler in the case of
wrong problems and definining NULL as ((void *)0) will make some WRONG
programs work.  I personaly believe that NULL should be defined as 0 to
punish people who disregard compiler warning messages.  I think my
belief is consistent with the aim of Andy Tanenbaum.

The answers in detail:

1. Is plain 0 a good definition fo NULL?

>From Samuel P. Harbison, Guy L. Steele Jr., C: A Reference Manual,
Second Edition, Prentice-Hall, 1987:

Page 91:  Every pointer type has a special value, ``pointer to
nothing,'' which is written as the integer constant 0.  Standard header
files usually define the preprocessor macro name NULL to be 0.


Page 283:
13 Standard Language Additions
[...]
13.1 NULL, PTRDEF_T, SIZE_T
#include <stddef.h>			/* ANSI */

#define NULL 0
[...]
The value of the macro NULL is the traditional null pointer constant.
Many implementations define it to be simply the integer constant 0.

>From the above it looks like #defining NULL to be 0 is a perfectly
correct and reasonable thing to do.

2. Are there any problems with defining NULL as ((void *)0) ?

In my opinion, no.  Correct programs will still run because ``a null
pointer of any type may be converted to any other pointer type and
still be recognised as a null pointer.'' (Harbison, Steele, page 133)


3. Will defining NULL as ((void *)0) enable some WRONG programs to
successfuly run on some architectures and C implementations?

Yes.  In some architectures and some C implementations WRONG programs
will work.  Here is an example for this:

file1:
#include <stdio.h>
void myputs(char *b)
{
	if (b)
		(void)puts(b);
}

file2:
#include <stddef.h>
main()
{
	myputs(NULL);	/* THIS IS WRONG, cast and/or prototype needed */
	exit(0);
}

Assume an architecture and C implementation where pointers are 4 bytes
long and integers are 2 bytes long.  Furthermore assume that the
representation of all null pointers (recall from Chris Toreks article
reposted by Rich Salz that different null pointers may have different
representations) is four zero bytes.  In this case if NULL is defined
as ((void *)0) calling myputs with NULL as an argument will push four
zero bytes on the stack and the program will work as intended.  If NULL
was defined as 0 then only two zero bytes would be pushed on the stack
and the program would behave in a nondeterministic way.  It could at
different circumstances crash, print garbage or print nothing,
depending on what the other two bytes on the stack were.

4. Will any of the two definitions of NULL make any difference on the 
diagnostic output of the compiler in the case of wrong programs?

In my opinion, no.  A well implemented compiler should complain in the
example given above that there no function prototype was given for the
myputs function.  Furthermore a well implemented compiler should not
complain about any assignments or comparissons of pointers with the
integer value 0:  If a null pointer of any type is created through
assignment or initialization by the integer constant 0, then the
conversion of that null pointer to an integer type must yield the value
0. (Harbison, Steele, page 131)

Diomidis
--
Diomidis Spinellis                  Internet:                 dds@cc.ic.ac.uk
Department of Computing             BITNET:                   dds@cc.ic.ac.uk
Imperial College                    UUCP:   ...!cernvax!cc.imperial.ac.uk!dds
London SW7 2BZ                      JANET:                    dds@uk.ac.ic.cc




Newsgroup comp.os.minix contents
Newsgroup list
Diomidis Spinellis home page

Creative Commons License Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.