Movement against float.init being nan

drug007 drug2004 at bk.ru
Mon Aug 22 13:33:56 UTC 2022


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?

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


> 
>> 3. compiler complains that `double x;` needs an initializer. To shut 
>> up the compiler, the user initializes it to 0, without putting much 
>> thought into it. bar(0) may exhibit problems, but these won't 
>> necessarily be noticed.
>>
>> 4. compiler complains that `double x;` needs an initializer. Coder 
>> just schlepps in a 0. Yes, this happens. Maintainer wastes time 
>> wondering why x is initialized to 0, as that may be a nonsense value 
>> for x. Maintainer wonders if this unused initialization has a purpose, 
>> maybe it is the result of a bad refactoring? Wastes more time 
>> investigating it.
> 
> Huh? Why are there 2 identical situations here?
> 
> I'll also point out that not initializing an integer is sometimes 
> intentionally done (because it's equivalent to initializing to 0). If I 
> see someone didn't assign a value to an int, I don't question if it was 
> an accident, I expect that they meant it.
> 
> Also, you forgot:
> 
> 5. Maintainer expected x to default to 0 (because that's what most types 
> do), and expected bar to be called with 0 or 5. Now, since bar saved the 
> result of it's calculation elsewhere, and then far away from this code, 
> the result is used in some computation that finally makes its way to 
> output in some fashion (and possibly not a specific printing of the 
> value), now there's a puzzle to solve, and no way to know it can be 
> traced back to x without hours/days of searching.
> 
>> D chose option 1.
> 
> And there's probably no way that it changes. But in my mind the correct 
> answer is to intialize to 0.
> 
> -Steve



More information about the Digitalmars-d mailing list