[comp.lang.c] strcat

diamond@jit533.swstokyo.dec.com (Norman Diamond) (06/13/91)

In article <1991Jun12.214124.24990@bronze.ucs.indiana.edu> lwm@bronze.ucs.indiana.edu (Larry Meehan) writes:
>In <1991Jun12.062045.13467@tkou02.enet.dec.com> diamond@jit533.swstokyo.dec.com (Norman Diamond) writes:
>>When a source program uses an integer constant 0 as a pointer, the compiler
>>must recognize it as a null pointer constant.  However, a null pointer
>>constant does not have to be address 0 at execution time.  If the source
>>program uses 0 for an integer, its binary value has to consist of 0-bits,
>>but for a null pointer it does not have to do so.

>I have always tried to avoid writing code that assumes anything about the
>value of NULL.  I have always felt uneasy about constructs like
>			while (*argv)
>and avoided them myself.  It sounds from what you say like this is a very
>dangerous (non-portable) line of code.

No.  This is perfectly portable and not dangerous.

>I mean, is the compiler expected to translate this to
>			while (*argv != NULL)
>on systems that have a non-zero value for NULL?

   while (*argv)
   while (*argv != 0)
   while (*argv != (void *) 0)
   while (*argv != NULL)
   while (*argv != (char *) 0)  /* only because  *argv  has type  (char *) */
are all equivalent.  The compiler is required to translate all of these to
   compare *argv to run-time representation of a null pointer
   if equal, jump out of the loop
   [contents of loop]
   jump back to the compare
The run-time representation might or might not be binary zeroes.
If the source code has integer constant 0, (void *) 0, or NULL,
(or, as in while (*argv), an implied occurrence of one of these),
in a place where it must be a pointer,
then the compiler is required to translate it to the run-time representation
of a null pointer.

However, for example,
   while ((int) *argv != 0)   /* casting pointer to int, and comparing ints */
   while ((unsigned long) *argv != 0)  /* approximately the same */
are unportable and dangerous.

>I realize this newsgroup is not about C programming, but this issue will
>probably continue to bite DEC customers who move from VAX to RISC, so it
>is probably good for it to appear here once in a while.

It will bite anyone who wrote code for an implementation represents null
pointers by all 0-bits (too many, IMHO, because all 1-bits would be easy
to trap on many Intel processors), or more accurately where fetching from
the location addressed by a null pointer does not trap, and then moves to
an implementation where it does trap.  I once read that some vendor had
changed their kernel to waste a page of (virtual and real) storage for
every process, because that was easier than fixing applications that came
from a certain irresponsible organization that should have known better.

Follow-ups are directed to comp.lang.c because it really is a language issue.
(Readers of comp.std.c probably don't want to be bothered by it again.)
--
Norman Diamond       diamond@tkov50.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
Permission is granted to feel this signature, but not to look at it.