[comp.lang.c] return value of free

bright@Data-IO.COM (Walter Bright) (01/28/89)

In article <287@proton.UUCP> proton!nusbaum@ucrmath.ucr.edu (R. James Nusbaum) writes:
>What is the story on the return value of free?

ANSI C says that the return value of free() is (unfortunately) void. The
reason I say unfortunately is that it now can't return an error status.
Zortech's free() returns an int which says whether it failed or not. If
it failed, this means that either the heap has been corrupted or an
attempt was made to free a wild pointer. The proper behavior then is to
print a message and abort the program before it crashes. free() cannot
guarantee that it'll always detect errors, but it does often enough that
this is a valuable feature.

You could argue that free() should internally print the message and abort.
This is an inferior solution, because the program may need to do some
cleanup before it exits, like restoring hooked interrupt vectors and
switching the display back to text mode.

I intend to leave it this way, and in stdlib.h have something like:
	#if __STDC__
	void
	#else
	int
	#endif
		free(void *);

P.S. I wrote Zortech C.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/28/89)

In article <1849@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>I intend to leave it this way, and in stdlib.h have something like:
>	#if __STDC__
>	void
>	#else
>	int
>	#endif
>		free(void *);

But this is wrong, except perhaps for Zortech C.  free() traditionally
never did return a value, although before "void" was added to C there
was no way to express this.

Note that none of the standard C library routines are specified with
provisions for indicating programmer usage errors.  This does not mean
that defensive programming is bad, merely that the burden for safety
checking was deemed better taken on explicitly by applications than by
the standard library.  For example, you could implement your own "safe"
alloc/dealloc routines as wrappers around malloc()/free().  In fact we
have done that for a large programming project I'm currently involved
with.  This technique has the advantage that time-consuming exhaustive
validation can be performed under optional debugging control, and when
a usage error is detected the error handling can be just what we want
it to be (we also have a special package for logging errors).  For such
a thorough job of usage validation, anything extra done in the standard
library would be a total waste of time.

For less careful applications, cheap tests for null pointers, etc. can
and probably should be done in the implementation of the standard
library.  Better to get an assert() failure during development than to
have the code run amok in unpredictable ways during production use.
But I don't think the standard library is any place to implement more
thorough safety checks.  Applications that want them will provide their
own, and know that their availability will not depend on the whims of
the C implementors.