Movement against float.init being nan

Steven Schveighoffer schveiguy at gmail.com
Mon Aug 22 14:16:14 UTC 2022


On 8/22/22 9:33 AM, drug007 wrote:
> On 8/22/22 14:41, Steven Schveighoffer wrote:
>> On 8/21/22 12:51 PM, Walter Bright wrote:
>>> Consider the following pattern, which doesn't appear frequently, but 
>>> frequently enough:
>>>
>>>      double x;
>>>      if (condition) {
>>>          x = 5;
>>>          ...
>>>      }
>>>      ...               // (1)
>>>      if (condition) {
>>>         foo(x);
>>>      }
>>>
>>> Imagine there's a lot more code omitted which obscures the pattern. 
>>> This code is correct.
>>>
>>> Now, maintainer adds `bar(x)` at (1).
>>>
>>> The scenarios:
>>>
>>> 1. x is default initialized to NaN. bar(x) produces a NaN result on 
>>> everything dependent on x. User knows there's a problem.
>>
>> How? No exception is thrown, no error occurs. Unless bar somehow 
>> checks for NaN, nothing happens. Just like it is for 0. Perhaps it 
>> saves the result of bar computation to something for later use. Then 
>> that now gets propagated to some other use, and then, deep somewhere, 
>> NaN appears in something that appears completely unrelated to bar or 
>> x. How do you trace it back?
> 
> For example, user has a callstack where called functions has these 
> return values:
> 
> float.init == 0                float.init == NaN
> 
>      13 <==  wrong result detected here  ==> NaN
>      0                     NaN
>      39                    NaN
>      56                    NaN
>      9 <==   wrong initialization here   ==> NaN
>      12                    12
>      0                     0
>      0                     0
> 
> In which case you find the reason faster?

Callstack printouts don't look like that. Plus, what if you don't have 
the call stack available for inspection? And even if you do, that 9 
might be just as obviously wrong as the NaN, negating any real benefit.

One thing that everyone seems to be ignoring is that 99% of the time, 
when I find out I didn't initialize a float and it's NaN, it's because I 
didn't correctly initialize it to 0.

So yes, when a lack of initialization somewhere in some code has 
happened *and is a mistake*, a NaN starting value can make things 
slightly easier, as long as you have everything instrumented, and can 
use a debugger. But *when* it happens is reduced to near zero if the 
default value is the expected 0.

>>> 2. x is default initialized to 0. bar(0) may exhibit problems, but 
>>> these problems won't necessarily be noticed.
>>
>> Just like NaN.
> 
> No. NaN is not a number but zero is a number. zero may be both wrong and 
> right value. NaN is never right result. To check if zero is right result 
> you need manually calculate it. In case of NaN all you need is to take a 
> look at it.

As I've mentioned, you don't always see the NaN, just like you don't 
always see the 0.

Imagine you are making a 3-d model, and one vertex out of 100k is NaN. 
How will you notice it? A single missing triangle somewhere?

But make that vertex 0, and all of a sudden your model has this weird 
triangle sticking out extending to the origin, and is completely obvious.

-Steve


More information about the Digitalmars-d mailing list