Movement against float.init being nan

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


On 8/22/22 9:17 AM, wjoe wrote:
> On Monday, 22 August 2022 at 11:41:33 UTC, 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?
>>
> 
> Assuming this isn't a rhetoric question...

It's not.

> It's not as convenient as a segfault but at some point, the error 
> becomes obvious.

Does it? And "at some point" it becomes obvious no matter what the error 
you made.

> I would start there to inspect variables, identify the 
> NaNs.

What if you can't? What if it only happens randomly, and you don't just 
happen to have a debugger attached?

I'm not saying it's easier with 0, but just not any different.

> Then I would trace them in a debugger and go up the call chain until I 
> find the location where it became NaN. Then I would identify the source 
> which introduced the NaN and trace that back until I found its origin.

If you have a chance to use a debugger and it happens at that time.

> 
> The advantage I see in NaN is that it's always (instead of only almost 
> always) immediately obvious that it's wrong whereas 0.0 can be valid or 
> invalid so you need to figure out which one it is which requires an 
> extra step.
> 

It might be noticed that it's NaN. It also might not. It depends on how 
it's used.

Either way, you need to find the source, and NaN doesn't help unless you 
want to start either instrumenting *all* code (possibly including code 
you don't control), or use a debugger (which isn't always possible).

Can we have some kind of linting system that identifies NaNs that are used?

-Steve


More information about the Digitalmars-d mailing list