X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Recipient: djgpp AT delorie DOT com From: "Stephen J. Turnbull" 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> <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 Content-Type: text/plain; charset=utf-8 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 Precedence: bulk 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.