ANSI C

Guy Harris guy at sun.uucp
Sat Aug 16 19:09:13 AEST 1986


> It's not too late.  In the first place, NULL already exists for this purpose
> (though some people insist on using it as a synonym for '\0' too!)  If zero-
> in-pointer-context henceforth produces a warning message, people will
> convert their programs to use NULL instead.  

Yes, but I don't know whether the disruption that would cause at this late
date would be worth the advantages the changes you suggest would bring.

	1) I've seen a fair amount of code that does things like

		<something> *p;
		...
		if (p == 0)

	(which is perfectly legitimate and type-correct C) and makes
	calls like

		execl("/bin/cat", "cat", "file", (char *)0);

	2) What happens to code like

		<something> *p;
		...
		if (p)

	or
		if (!p)

	which is also, at least by my interpretation of the August 11,
	1985 ANSI C draft, perfectly legitimate and type-correct C.
	The discussions of Boolean objects (now that Root Boy is gone,
	I guess we can acknowledge the existence of Boolean objects in
	C again) in the draft talk use terms like "equals 0" or "does
	not equal 0"; I presume some expression X "equals 0" iff X == 0,
	and "does not equal 0" iff X != 0.  Both of those comparisons
	can be done on pointers.


The code in both these examples will have to be changed.  The ANSI C
committee is at least trying not to break existing code any more than is
absolutely necessary.

> NULL would presumably be changed from "0" to an implementation-defined
> constant like "(void *)0xF0000000".

Blech!  I suppose the compiler will recognize expressions like that and, if
it treats null pointers in any special way, will treat them as such, but it
seems ugly.  (Yes, a compiler *could* treat them in usefully special ways.
For instance, it might try to do dataflow analysis and figure out whether
you run the risk of dereferencing a NULL pointer or not.  Said dataflow
analysis would have to be interprocedural, of course, and cross module
boundaries; however, given the depressing amount of crap code out there that
is careless about null pointers, it might be worth it.)

> Hmm, there's a similar problem without the full-check conversion.  If the
> constant zero is converted into a null pointer constant, and zero is a valid
> address, and something of interest is at that absolute address, how do I
> reference it?  "x = *(int *)0" will try to dereference NULL instead of 0,
> and "i = 0; x = *(int *)i" will undoubtable fail on some optimizing
> compilers.

Why?  If the compiler implements C, it will NOT combine the two statements
into one, since the meaning of "x = *(int *)0" is undefined, but the meaning
of "x = *(int *)i" is defined to the extent that conversions of "int" to
"int *" is defined.  The optimizer might decide that the value of "i" is
known at that point, and compute the value of "(int *)0" at compile time,
and generate code to load the "int" value that would be located at that
address into "x".  It might then discover that "i" is dead at that point,
and throw it away.  No C compiler will generate code to dereference a null
pointer for that example; any compiler that does is compiling a language
other than C.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy at sun.com (or guy at sun.arpa)



More information about the Comp.lang.c mailing list