Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!uwvax!uwmacc!hobbes!root
From: root@hobbes.UUCP (John Plocher)
Newsgroups: comp.unix.xenix
Subject: Re: Microport Users' Group Bug List
Message-ID: <158@hobbes.UUCP>
Date: Sun, 26-Jul-87 15:31:47 EDT
Article-I.D.: hobbes.158
Posted: Sun Jul 26 15:31:47 1987
Date-Received: Tue, 28-Jul-87 00:38:34 EDT
References: <166@qetzal.UUCP> <157@hobbes.UUCP> <245@ddsw1.UUCP>
Reply-To: root@hobbes.UUCP (John Plocher)
Followup-To: poster
Organization: U of Wisconsin - Madison  Spanish Department
Lines: 126

Followup to the NULL pointer stuff in the comp.lang.c group, please.

+---- Karl Denninger writes the following in article <245@ddsw1.UUCP> ----
| John Plocher writes:
| > +---- (Robert White) writes
| > | 10. Passing (char *) NULL to a function in a large model program can cause
| > | a core dump/program abort.
| >   WRONG!  Passing the NULL pointer is not what is wrong!  What IS wrong
| >   is the ASSUMPTION that the data stored at location NULL is anything useful
| 
| Hmmm... Some things to consider:
| a)	NULL is declared in large model programs to be '0L' (look in the
| 	header file)

This is 100% WRONG!  Microport SCREWED IT UP!  NULL should be 0, not 0L!
The reason it is incorrectly set to 0L is that programmers rarely bother to
cast NULL when passing it as a parameter to functions:  foobar(NULL); is wrong.
It should be done like this:  foobar( (char *)NULL );

(See discussion in comp.lang.c from March 87)

| b)	(char *) variable, where variable contains 0, works in this
| 	situation. (char *) NULL does not.

WRONG.  Neither work.  An example:

	/* cc -Ml foo.c ; a.out */
	#include 
	main() {
	    int p;
	    p = 0; 	/* "(char *) variable, where variable contains 0" */
	    printf("int: %s\n",(char *)p);
	    printf("NULL: %s\n",(char *) NULL);
	}

	This routine "segmentation faults" in the 1st printf().  Why?

	On page 97 of K&R it states:
	    "C guarantees that no pointer that validly points at data
	     will contain zero, so a return value of zero can be used
	     to signal an abnormal event, in this case, no space.  We
	     write NULL instead of zero, however to indicate more clearly
	     that this is a special value for a pointer."

| c)	I am *not* passing NULL, but rather a POINTER to it. The value
| 	pointed TO at that location should BE the null!

	What you said:   char *p = "\0";  /* A pointer to an array with NULL */
					  /* the value of the first element */
		    -or-
			 int x;		  /* a place for a value */
			 int *p;	  /* a pointer */
			 p = &x;	  /* points to the variable x which */
			 *p = 0;	  /* now contains a value of zero */

	What you did:    char *p;	  /* A pointer ... */
			 p = 0;		  /* ...whose value is NULL */

	Do you see the difference?  In graphical terms:

		       variable     contents of		  contents of
			name	     variable		memory address1
		       --------     -----------		---------------
	What you said:	  p:        [ address1 ] ----------> [ 0 ]
	What you did:     p:        [ 0 ]

In the first case you have a pointer TO the memory location which contains
the value zero.  In the second case you have a pointer WHOSE VALUE IS zero.

By virtue of K&R (quoted above) a pointer whose value ia zero CAN NOT 
POINT TO ANYTHING, much less the value 0!  If it does HAPPEN TO WORK,
"this kind of code in inherently risky, for it depends on details of
implementation and machine architecture which may not hold for the
particular compiler you use."  Unfortunately, the VAX pcc compiler, the
80386 pcc compiler, and a few others have decided that a pointer whose value
is zero also points to a zero value:

	p:[ 0 ] -------> [ 0 ]

This did make life easier for lazy programmers: (What happens if this is
passed a NULL pointer?)

	while (*s++) { ... }		/* Works on a VAX, but not on a Sun */

instead of the correct (and robust and portable):

	while ( s && *s++) { ... }

| Will be more than happy to eat my bug report if there's a good reason why
| the cast which I included does not produce the desired result -- especially
| if someone can explain why example (b) works!

Example (b) does not work.   (-: Munch Munch? :-)

| > +----
| > | 17. Along the same line, so is 'ps' with no arguments (produces nothing,
| > | should show your processes.) 'ps' with arguments works fine. New problem
| > | with 2.2.2.
| > +----
| I *have* removed the file /etc/ps_data -- makes no difference. Here we get
| only the banner (PID, etc), and NO data -- unless you specify a switch like
| 'ps -ef', then it works fine!

	MAKE SURE that /unix is linked with /system5!  Other than that, I
	don't know what could be the problem.  My stuff works.  Also note
	that /bin/ps has not changed!

    >> uname -a
    system5 hobbes 2 2.2.2-L AT
    >> ls -la /unix /bin/ps
    -rwxr-sr-x   1 root     sys        29202 Oct 26  1985 /bin/ps
    -rw-rw-r--   3 bin      bin       290011 Jun 19 00:26 /unix
    >> ps
       PID TTY      TIME COMMAND
       105 cons3    0:05 csh
      9316 cons3    0:12 csh
     21023 cons3    0:00 ps
    >>

| Karl Denninger				UUCP : ...ihnp4!ddsw1!karl
| Macro Computer Solutions		Dial : +1 (312) 566-8909 (300-1200)

- John		^G: +1 (608) 655-3691	Karl, call me if you want...

-- 
John Plocher uwvax!geowhiz!uwspan!plocher  plocher%uwspan.UUCP@uwvax.CS.WISC.EDU