NaNs Just Don't Get No Respect

Davidson Corry davidsoncorry at comcast.net
Mon Aug 20 17:45:05 PDT 2012


On 8/18/2012 9:05 PM, Nick Sabalausky wrote:

> No offense taken (or intended), but I think you're conflating the
> different branches of the discussion.

I'm glad. And it's entirely likely that I missed something. I didn't 
read the whole thread, I was just replying to your one message. Lazy...

> 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.

Fair enough. I agree with you that the claim is in error -- not because 
I think the > operator should be pointing <, but because the two things 
are unrelated and shouldn't be compared. One is a compile-time check, 
the other a runtime minefield. One is a logic analysis, the other an 
out-of-domain value test. They are not XOR -- *both* should be used. 
(And some of us clever programmers will slip bogus programs past both of 
them anyway...)

>> 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...
>
> 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."

So true. But the only technology I have found to date capable of such 
insight is a good code review. And a good reviewer who is willing to 
take the time and analyze my code in depth (and then patiently and 
politely get past my mule-headed stubbornness and get me to see what 
he's saying) is a treasure beyond price. Man, if you can package *that* 
in a compiler, I'm buyin'!

>> 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.

I apologize. I did not mean that *you personally* were advocating 
specific "not an integer" values like -1. I meant the generic "you" as 
in many APIs that I am sure you are familiar with. Certainly there may 
be applications where a human-recognizable "dead beef" flag works 
well... and others where you don't want to drop a "not a value" value 
into the middle of a useful range. (0xDEADBEEF is not a useful value, 
but 0xDEADBEEE and 0xDEADBEF0 are??)

What I was trying to say was that programmers re-invent the "not a valid 
value" trick all the time. For example, the Unicode Consortium defines 
the code point 0xFFFE to be an invalid character, and thus allows tricks 
like the Byte Order Mark. In my own specialty of Windows installer work, 
a zero exit code marks "success" and a non-zero exit is "failure"... 
except that the special values of decimal 3010 and (archaically) 8192 
flag "success but reboot required to complete the install". NULL and 
nullptr are special values for C/C++. And so on.

I have needed a flag to indicate a Boolean with a one-time 
initialization often enough to have written a small class to encapsulate 
the True|False|NotYetSet behavior. And it lacks rigor. For instance, it 
does not have the "taints all downstream expressions" behavior that 
floating NaN does. One of these days I will rewrite it correctly and add 
it to a library.

>> ...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 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".)

OK. Well, you may need to write your own compiler, then. You and Walter 
may be enlightened enough to gain insight through earnest reason 
together. Me, you usually have to hit me over the head with something 
heavy a couple of times before I get your point. <grin> Ouch.

-- Davidson



More information about the Digitalmars-d-announce mailing list