if (p), where p is a pointer - PLEASE READ

rex ballard rb at ccivax.UUCP
Fri Sep 20 09:38:17 AEST 1985


> An C idiom I see (and write) frequently is
> 
> 	if (ptr)
> 
> Will this work correctly on a machine where NULL is not 0?  Does it really
> need to say
> 
> 	if (ptr != NULL)
 
If you have the K&R book page 97 says:
	We write NULL instead of zero however, to indicate that this is
	a special value for a pointer.  In general, integers cannot
	meaningfully be assigned to pointers; zero is a special case.

If you have the use the "C referrence manual", section 7.14 states:

	The compilers currently allow a pointer to be assigned to
	an integer, an integer to a pointer, and a pointer to 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 addressing
	exceptions when used.  However, it is guarenteed that
	assignment of the constant 0 to a pointer will produce a
	null pointer distinguishable from a pointer to any object.

In other words, if NULL is defined as anything other than 0, you
are going to blow your banana's if you try to compile someone elses
code.

If you are really insistant, you can even access address location 0
in memory on some machines since many segmented systems like to
have the first byte of executable code.  The important thing here
is that you are not explicitly required to CAST a NULL for fear of
loss of significant bits, sign extension, or similar problems associated
with cross-type comparisons (like comparing 0126 < '\240') which
require explicit casting.

A popular convention is to use the "(char *)0" definition.  This can
get confusing if your source code contains (int *)NULL.  Some (the
bad ones) versions of lint give interesting results.

Always be sure however of the exact definition of the returned pointers such as
EOF is not as consistant.

I recently experienced a nasty "gotcha" in an interface with two routines
each of which returned 'OK' but the problem was:
--------------------------
(file 1)
#define OK 0	/* actually include's */

foo()
{
	return(OK);
}
-----------------------------
(file 2)
#define OK -1	/* actually include's */

fie()
{
	return(OK);
}
-----------------------------
(file 3)

foobar()
{
	if(!foo()||!fie())
	{
	  errmsg("oops");
	  return;
	}  /* I normally use "indent -bl" but not on mail */
}

Of course foo and fie were very frequently used routines used in
separate products so there was no way to fix the various users
(many of which used "if(~fie())").

The first example is good it you are certain the function returns NULL,
otherwise, forget it.


By the way, has anybody figured out how to get lint to shut up about
the return codes for { ,s,f}printf().  I have yet to see a standard definition
of the return code, but lint keeps giving me "value returned but not used".
Isn't this just a tramp from doprntf?  I've had one version hand back the
value of write (and blew away my stack) even though the return code was
supposed to return a char* (sprintf),  (Seems it didn't like writing a
4k message).  This appears to be a good case for using if(sprintf(...)).



More information about the Comp.lang.c mailing list