delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2013/07/31/00:38:38

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
From: "Stephen J. Turnbull" <turnbull AT sk DOT tsukuba DOT ac DOT jp>
To: djgpp AT delorie DOT com
Subject: Re: _CRT0_FLAG_NULLOK
In-Reply-To: <3df2f50f-9543-47a7-8e40-a9be82ce5018@googlegroups.com>
References: <21e77579-1a40-4442-8111-fc976fba78fc AT googlegroups DOT com>
<b5o37qFldl9U1 AT mid DOT dfncis DOT de>
<f24e8cd3-83ca-4386-a319-a9adb4d74c68 AT googlegroups DOT com>
<3df2f50f-9543-47a7-8e40-a9be82ce5018 AT googlegroups DOT com>
X-Mailer: VM undefined under 21.5 (beta32) "habanero" b0d40183ac79 XEmacs
Lucid (x86_64-unknown-linux)
Cancel-Lock: sha1:mlq6nNbKDDlS3UErMMp0CIN88Qc=
Date: Wed, 31 Jul 2013 13:38:16 +0900
Message-ID: <87fvuvny2v.fsf@uwakimon.sk.tsukuba.ac.jp>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

Georg Potthast writes:

 > I still feel it would be a better "user experience" if atoi() would
 > not crash. As far as I understand the specification does not
 > require atoi() to crash if a NULL pointer is passed.

No, it doesn't.  But "not crashing" is not necessarily a better end
user experience, although it may allow a programmer to save a few
lines.  It is not possible to give a consistent specification of what
happens when NULL is passed to a function, because by definition (C
standard) there can be no valid data pointed to by that pointer.
Therefore any behavior is necessarily arbitrary.

If you chose to avoid the crash via OS trap by testing for the special
case and returning 0, you may be screwing the end user by covering up
a bug.  The NULL pointer comes from somewhere; surely, the literal
expression "atoi(NULL)" is very rare in your programs.  So most likely
some other function is failing to do its job.

The DJGPP implementation is therefore functionally equivalent to

    assert(cp);
    return atoi(cp);

which identifies the bug earlier (perhaps much earlier) than doing a
postmortem analysis on a corrupted database, for one example.  It
encourages defensive programming:

    if (cp)
        return atoi(cp);
    else
        /* Reproduces True64 behavior.
           More complex error recovery is easily substituted. */
        return 0;

which is pretty much universally recommended by coding standards,
although programmers often don't bother.  Sometimes, where all callers
have been verified, the overhead of the check can be avoided
completely.  This is a performance improvement, in accordance with the
general philosophy of C that it's the programmer's responsibility to
assure correctness at any level above machine language, while the C
compiler provides the most efficient but correct implementations
possible for its constructs.

If you really like the "safe" behavior, it's trivial[1] to accomplish
efficiently by defining a tiny function (modern compilers will almost
certainly inline it, which will be a tiny bit faster than implementing
the branch in the function, since in the NULL case the function call
overhead is avoided).


Footnotes: 
[1]  In a one-file program.  In a multi-file program getting this to
work without defining the function many times is wizard's work.  Of
course, if you're confident that your compiler will inline it, that
doesn't matter.  Or you can change the signature and use a macro.


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019