From xemacs-m  Sat Jun 21 14:02:33 1997
Received: from mercury.Sun.COM (mercury.Sun.COM [192.9.25.1])
	by xemacs.org (8.8.5/8.8.5) with SMTP id OAA19993
	for <xemacs-beta@xemacs.org>; Sat, 21 Jun 1997 14:02:32 -0500 (CDT)
Received: from Eng.Sun.COM ([129.146.1.25]) by mercury.Sun.COM (SMI-8.6/mail.byaddr) with SMTP id MAA24637 for <xemacs-beta@xemacs.org>; Sat, 21 Jun 1997 12:24:28 -0700
Received: from kindra.eng.sun.com by Eng.Sun.COM (SMI-8.6/SMI-5.3)
	id MAA05010; Sat, 21 Jun 1997 12:01:52 -0700
Received: from xemacs.eng.sun.com by kindra.eng.sun.com (SMI-8.6/SMI-SVR4)
	id MAA27313; Sat, 21 Jun 1997 12:01:52 -0700
Received: by xemacs.eng.sun.com (SMI-8.6/SMI-SVR4)
	id MAA08300; Sat, 21 Jun 1997 12:01:50 -0700
Date: Sat, 21 Jun 1997 12:01:50 -0700
Message-Id: <199706211901.MAA08300@xemacs.eng.sun.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
From: Martin Buchholz <mrb@Eng.Sun.COM>
To: Hrvoje Niksic <hniksic@srce.hr>
Cc: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: Re: Yet more 64bits lossage
In-Reply-To: <kiglo445ua5.fsf@jagor.srce.hr>
References: <19970621012424.18989@iria.mines.u-nancy.fr>
	<199706210604.XAA07502@xemacs.eng.sun.com>
	<19970621082753.50969@iria.mines.u-nancy.fr>
	<kiglo445ua5.fsf@jagor.srce.hr>
X-Mailer: VM 6.32 under 20.3 "Oslo" XEmacs Lucid (beta7)
Reply-To: Martin Buchholz <mrb@Eng.Sun.COM>

>>>>> "Hrv" == Hrvoje Niksic <hniksic@srce.hr> writes:

>> which makes much sense. NULL _should_ be the size of a pointer on
>> any reasonable compiler, but we're in the real world :/

Hrv> No,

Hrv> #define NULL 0

Hrv> is sufficient in every ANSI C implementation.

Hrv> 5.2:	How do I get a null pointer in my programs?

Counter-No.

A definition of NULL as 0 is sufficient if application writers always
cast NULL to pointer in an ambiguous context like varargs argument
lists.  Almost everyone is guilty of getting this wrong, including us
and the O'Reilly manuals (read the docs for XtVaSetValues).  The X
docs assume that using NULL is good enough.

So the OS should provide a better definition of NULL.  In particular,
it must satisfy these requirements:

1. sizeof(NULL) == sizeof(void *), so the natural (albeit buggy) code

printf("%p", NULL);

prints "0"

3. The code

int foo(char*);
foo(NULL);

compiles cleanly under C *and* C++.
(This is why
#define NULL ((void *)0)
doesn't work.)

Since, in practice, sizeof(long) == sizeof(void*) is almost always
true,

#define NULL 0L

works on almost every system, and is a better definition for NULL.
In particular, it's a better definition on Irix 64.

This kind of stuff is really tricky to get right.  The published C
standard itself once made the mistake of suggesting

#define NULL (void*)0

(without an extra set of parens) as a valid definition of NULL,
which leads to

NULL[argv]

(incorrectly) compiling cleanly instead of correctly generating an
"incompatible types" warning.

Martin

Hrv> A:	According to the language definition, a constant 0 in a pointer
Hrv> 	context is converted into a null pointer at compile time.  That
Hrv> 	is, in an initialization, assignment, or comparison when one
Hrv> 	side is a variable or expression of pointer type, the compiler
Hrv> 	can tell that a constant 0 on the other side requests a null
Hrv> 	pointer, and generate the correctly-typed null pointer value.
Hrv> 	Therefore, the following fragments are perfectly legal:

Hrv> 		char *p = 0;
Hrv> 		if(p != 0)

Hrv> 	(See also question 5.3.)
Hrv> [...]


Hrv> The problem with variable-width argument lists is that the compilers
Hrv> cannot know whether there is an integer context, or a pointer
Hrv> context.  Thus one should always cast the pointers when calling such
Hrv> functions:

Hrv> execlp ("foo", "foo", "-v", (char *)0);

