retiring gets(3)

Jim Patterson jimp at cognos.uucp
Wed Nov 16 03:00:04 AEST 1988


In article <7963 at bloom-beacon.MIT.EDU> scs at adam.pika.mit.edu (Steve Summit) writes:
>After we get rid of gets, we should get rid of calloc(n, size),
>which doesn't really do anything for you that malloc(n * size)
>doesn't do.calloc's only claim to fame is specious; its zero fill
>property is misunderstood by many programmers and is sufficiently
>useless that it can easily be replaced by bzero and/or memset for
>those few instances that truly require filling with bytes of zero.
>(Recall that such a zero fill does not necessarily result in NULL
>pointers or 0.0 floating-point values, in the common case where
>arrays or structures are being allocated.)

I've seen this point made many times, and it's even in the ANSI draft
standard that null pointers don't HAVE to be all-bits-zero (as opposed
to the "null pointer constant", which IS required to be 0).
Realistically, though, are there REALLY C implementations out there
which don't take binary 0 to be a NULL pointer, or a floating-point
datum of all zero bits to be other than 0.0? I would be very
interested in hearing about such systems.

I know of at least one system where the system convention is not 0;
Data General MV systems have instructions which take -1 as the null
pointer value, and this has persisted through many system call
conventions as well. However, the C implementation still considers a
null pointer to be 0 even though this requires quite a bit of "glue"
around some system calls to interface between the two formats.
Requiring that the "null pointer constant" be 0, as ANSI C does, just
makes any other implementation painfully difficult (and is begging for
problems when porting software as well).

I don't consider calloc() specious; if you have a large table to
allocate even memset() can be too much overhead if you can do it
better. Explicitly setting all elements of a table to the appropriate
sort of 0, while maximally portable, is definitely even less efficient
(assuming your memset implementation isn't completely out to lunch).
If efficiency isn't a problem, fine, but often it is.

Where a good implementation of calloc() can shine is in virtual memory
(VM) environments where it can avoid actually faulting in the pages
that you allocate. On many VM systems you can do this using a
demand-page-zero page type which is allocated and cleared to zero when
it's first referenced (VAX VMS is one system that supports this).  You
can't take advantage of this using malloc() and memset() (or explicit
initialization). You are forced to fault in the entire area to clear
it to zero, even though if it's a large area much of it will likely be
faulted out again before you reference it again (if you do).

It's worth noting that pre-clearing memory shouldn't be considered
wasted overhead on the part of the OS. It's an important security
precaution, to prevent other system users from poking through memory
that used to belong to someone else and which could contain sensitive
information. This may not be important to all users, but it is to
many.
-- 
Jim Patterson                              Cognos Incorporated
UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707    
PHONE:(613)738-1440                        3755 Riverside Drive
                                           Ottawa, Ont  K1G 3Z4



More information about the Comp.lang.c mailing list