NaNs Just Don't Get No Respect
Nick Sabalausky
SeeWebsiteToContactMe at semitwist.com
Sat Aug 18 21:05:28 PDT 2012
On Sat, 18 Aug 2012 20:16:37 -0700
Davidson Corry <davidsoncorry at comcast.net> wrote:
> On 8/18/2012 7:36 PM, Nick Sabalausky wrote:
> > If that's the case, then the code is far too damn fragile in the
> > first place.
> >
> > This:
> >
> > float f;
> > if (condition1)
> > f = 7;
> >
> > Is bad fucking code, period. I'd expect *ANY* usage of f after that
> > (except, of course, a plain assignment to it) to be flagged as an
> > error. That's because *even if* f isn't technically used without
> > assignment, it still indicates that somebody didn't think their shit
> > through and may already be hiding a bug (in which case they're
> > damnned lucky it's a float instead of an int) - and even if not,
> > then it's still too damn fragile anyway and *will* likely wind up
> > creating a bug once someone goes and touches that code.
> >
> > FWIW, Last time we debated this on the NG, this was the point where
> > Walter got stuck on the irrelevant "But it's not garbage-inited
> > like C!" strawman. I hope we can do better this time.
>
> With respect, I think that you are conflating two different questions.
>
> If the question is, "should static checking reject this code as
> flawed?", then NaN is irrelevant, and a strawman, yes.
>
> But if the question is, "is default-initializing to NaN better than
> default-initializing to garbage?", then it's entirely on point. (And
> that is the topic of this thread.)
>
No offense taken (or intended), but I think you're conflating the
different branches of the discussion.
The "NaN-initing better than garbage/zero-initing" was a key
point of the OP, yes, but not of all branches of discussion, and not
the only point in the article either.
Please reread the thread and notice that the branch I was replying to
was directed specifically at this section of the article:
--------------------------------------
Given the code:
float f;
if (condition)
++f;
the user writes "in language X, the compiler complains on line 3 saying
that f is used without being initialized. Isn't that a better
solution?" For that example, it probably is a better solution. But
consider:
float f;
if (condition1)
f = 7;
... code ...
if (condition2)
++f;
[Goes on attempting to build a case against the static checking]
--------------------------------------
So yes, the OP *IS* claiming "NaN-initing > conservative static checks"
and that is what this branch of the thread, including the post I
directly replied to, was directly addressing.
> Yes, it would be great if the D compiler (or a C++11 compiler, or C#
> or Scala or what have you) could do a complete static check of the
> code. As a practical matter, today's compiler technology cannot. (And
> if it could, you'd get complaints about compile times... <grin/>)
>
Actually, I disagree. I want a static check, but I *don't* want it to
be complete. Largely because of the difficulty of doing so and the
compile times, yes, BUT also because (as I already said) code such as
this:
float f;
if (condition)
++f;
// Complex stuff that may involve f in certain codepaths
Is *already* fragile and bad, and could easily hide/generate bugs even
with NaN. In fact, there's a reasonable chance it may already be a bug,
again even with NaN. And even with NaN, it would still be much better to
just get an error for the whole damn thing: "ERROR: This is screwy
fucking code. Even if it's not technically buggy right now, which is
questionable anyway, it can easily become a bug if it gets altered
without being very, VERY careful. So go back and rewrite it to not be so
damned fragile."
> Since the flaw may not be detected statically at compile time, it's
> nice to know that NaN will detect it at runtime (in the same sense
> that a minefield "detects" an intruder).
>
I'm advocating conservative static checking. It WILL be detected at
compile-time (along with some false positives, but I've been arguing
these are GOOD false positives, or *at least* perfectly acceptable).
> Consider how useful *integer* NaN is. Oh, you didn't realize that,
Please don't put words in my mouth. I've advocated in past discussions
for making 'int.init' be 0xDEADBEEF or 0x69696969 as a
"next-best thing" for when (as with D) static checking isn't performed.
> when you used zero, or minus one, or 0xFFFF or its moral equivalents,
> to flag an error or exceptional condition on a function that returns
> what is normally a number, that you were hand-rolling an integer NaN?
> For that matter, wouldn't it be nice to have a Boolean NaN? (not
> "true", not "false", but "not yet decided")
>
> Except of course that zero, and one, and minus one, and all-bits-set
> are all extremely common and useful *arithmetic* values, and all too
> likely to be returned legitimately. So having a hardware NaN in
> floating point, particularly one that "taints" all future results it
> participates in, and further one that can (by definition) never be a
> legitimate number, is genius. And having Walter design D to take
> advantage of it is... well, perhaps not genius, but damned smart.
>
Right. But what's *even smarter* than that, is just eliminating the
whole f***** problem at compile-time. Walter has specifically argued
against the wisdom of that on various occasions (including in this
article), and what I'm saying is that I don't buy *that* reasoning or
its conclusion. (And then I went on and bitched about a previous
discussion where he kept trying to use "NaN/0-init > garbage-init" as a
rebuttal to my completely *different* argument of "static checks >
NaN/0-init". Hence the "strawman".)
More information about the Digitalmars-d-announce
mailing list