From: hansen@pegasus.att.com (Tony L. Hansen)
Subject: Re: strdup() Was: Re: Renew?
Organization: AT&T
Date: Fri, 31 Jul 1992 14:22:46 GMT
Summary: to check for 0 or not to check for 0, that is the question
Keywords: operator new, strdup

< From: jbuck@forney.berkeley.edu (Joe Buck)
< In article <1992Jul29.155252.7632@cbnewsk.cb.att.com> hansen@pegasus.att.com (Tony L. Hansen) writes:
<< By the way, at least one person has posted a poor version of strdup()
<< which didn't check the return value of new. Here's my contribution. As
<< you can see, it is a very straightforward function: [ nstrdup that checks
<< value of new ]

This version of nstrdup() was written to be exactly equivalent to strdup().
Here's the description of strdup() from one manual:

    The strdup function allocates storage space (with a call to malloc) for
    a copy of string and returns a pointer to the storage space containing
    the copied string. The function returns NULL if storage could not be
    allocated.

< Sorry, Tony, I disagree.  This is the whole reason that exceptions were
< added to the language, so we wouldn't have to do this.  In the case of new
< failures, there is already a mechanism present: the "new handler".

< The proper approach is to use set_new_handler establish a handler to catch
< new returning 0, and have it either free up some memory or exit the
< application cleanly.  Those in memory-poor environments (IBM-PCs and such)
< may disagree.

< Given this philosophy, my version was just fine, thank you.

Philosophically you may be correct. Pragmatically you're barking up the
wrong tree. There may indeed come a time when operator new invokes an
exception when it runs out of memory. Even then, it may be completely
optional and the current rule of returning 0 on memory exhaustion may still
be the default. That is yet to be determined by the ANSI/ISO C++ committee.

Some people set the new handler and others don't, feeling perfectly
comfortable with checking the return values from new.

As a library developer, and nstrdup() is of the nature that it belongs in a
library, I have to be pragmatic. Current compilers DO return 0 on memory
exhaustion when there is no new handler, so library routines which will be
used by numerous people in numerous different programs and which work with
current compilers MUST check for 0 returns. Doing otherwise is doing a
disservice to the users of the library routine.

< If nstrdup checks for new returning 0, we then have to check for nstrdup
< returning 0, and so on.  Your nstrdup has just passed the problem on to
< someone else.

Actually, it's no different from strdup(), which also returns a 0 if
malloc() failed. And it's no different from new: if you have a new handler
present, you'll never see the 0, so you won't have to check for it. If you
don't have a new handler present, nstrdup() will act exactly like new,
passing on the 0 that it received, which the programmer had better be ready
to check for because they're the one that decided not to use the new
handler.

					Tony Hansen
			    hansen@pegasus.att.com, tony@attmail.com
				att!pegasus!hansen, attmail!tony
Xref: sparky comp.lang.c++:11821 comp.windows.ms:18117 comp.windows.ms.programmer:7440