What machines core dump on deref of NULL?

John Chambers jc at minya.UUCP
Fri Jul 6 11:17:10 AEST 1990


In article <1990Jun29.132304.12550 at athena.mit.edu>, jik at athena.mit.edu (Jonathan I. Kamens) writes:
> 
>   From K&R Second Edition, Page 102: "C guarantees that zero is never a
> valid address for data, so a return value of zero can be used to signal
> an abnormal event, in this case, no space."  ANSI C is a lot newer than
> "about a decade ago." 

And on page 192 of my C bible I find the paragraph:
	The compilers currently allow a pointer to be assigned to an integer,
	an integer to a pointer, and a pointer to a pointer of another type.
	The assignment is a pure copy operation, with no conversion.  This
	usage is nonportable, and may produce pointers which cause address
	exceptions when used.  However, it is guaranteed that assignment of
	the constant 0 to a pointer will produce a null pointer distinguish-
	able from a pointer to any object.

The trouble with this statement is that I've never seen a C compiler
that implements it.  On extant processors, it is simple to prove that
it can't be implemented.  If you examine any of the current commercial
processors (68xxx, 8xx86, SPARC, MIPS, PDP11/VAX, etc.), you quickly
learn that all of them have the property that there is no bit pattern
that is guaranteed to cause a fault when used as an address.  True,
you can use the memory-management hardware to intercept attempts to
reference ranges of addresses, but this is a different issue.  The
memory-referencing hardware has no bit pattern that a compiler can 
use as "null" value, with the guarantee that its use as an address
will cause an interrupt under all circumstances.  All bit patterns
are legal (byte) addresses on these machines.

Yes, I'm aware that processors have been built that have a null pointer,
and some even have a bit pattern that is recognized as not-a-number by 
all the arithmetic opcodes.  I've written code (even assembly code) for
the Burroughs B5500 and B6700, for instance.  I also think that having
an explicit "illegal" value for all types is a Real Good Idea.  But in 
today's real world, the programmers who write the really low-level stuff 
rarely have the luxury of a well-designed processor; they are stuck with 
80386s and the like.  On such processors, C simply can't be implemented 
in conformance with such standards, no matter how much we'd like it.

>   It would seem to me that a simpler solution to the embedded processor
> problem than requiring a non-standard C compiler in order to write code
> for one would be to not have any physical memory at address 0, or to put
> program memory there (since, unless the program is self-modifying, it
> should never have to access its own memory, excluding perhaps function
> pointers).

So how do you get the code there?  

If I were designing my own processor, I'd probably try to make address 
zero illegal, since that would catch so many bugs during early testing.  
But I'm not, and I can't.  Given hardware that says that such-and-such 
is stored at address zero, you either write code that references address 
zero, or you hand the job over to someone else.  You also tend to use 
the C compilers that are available, since you need to get a product out 
the door, rather than wait until an acceptable compiler comes along and 
you get a signature on the purchase order.

BTW, perhaps this should be asked in comp.lang.c (though I recall it
being discussed a few years back, with much flamage but few answers);
can anyone show how one would portably code a statement that assigns
the value zero (not null) to a pointer?  If I am faced with hardware 
with a given structure in low memory, it'd help if I could declare:
	struct lowmem {
		...
	} *lowmem = 0;
and be guaranteed that it will point to the right place.  It'd also
be nice to be able to do the assignment at run time if necessary. 
As so many people have pointed out, the above code could legally be
implemented as any illegal value; what I need is a way to guarantee
that it will be zero, regardless of what null is and whether zero 
is a legal address at the moment.

BTW, this issue could come up for some people working in the Unix
kernel.  Unix isn't immune from the clever ideas of the hardware
implementors.  Very often the interrupt vector table is in low
memory, and you just might find yourself someday working with a
kernel that allows interrupt routines to be added and deleted from
a running system.  (After all, VMS can do it, as can DOS.)  How
do you plan to plug in a new level-0 interrupt routine on this
system, if you can't write to location zero?  As any 80x86 hacker
will tell you, ranting about the idiocies of the design won't help 
you get the system out the door (though it surely does feel good 
at times ;-).

-- 
Typos and silly ideas Copyright (C) 1990 by:
Uucp: ...!{harvard.edu,ima.com,eddie.mit.edu,ora.com}!minya!jc (John Chambers)
Home: 1-617-484-6393
Work: 1-508-952-3274



More information about the Comp.unix.wizards mailing list