Disallow (dis)equality with FP.nan/FP.init literals

so so at so.so
Wed Apr 18 18:36:10 PDT 2012


On Thursday, 19 April 2012 at 01:28:51 UTC, so wrote:
> On Thursday, 19 April 2012 at 00:50:09 UTC, bearophile wrote:
>> This is an open enhancement request that I'll probably add to 
>> Bugzilla.
>> The direct cause of it is a recent discussion in D.learn, but 
>> I and other people are aware of this problem for a lot of time.
>>
>>
>> Since a lot of time D statically refuses the use of 
>> "classReference == null":
>>
>> // Program #1
>> class Foo {}
>> void main() {
>>    Foo f;
>>    assert(f == null);
>>    assert(f != null);
>> }
>>
>>
>> test.d(4): Error: use 'is' instead of '==' when comparing with 
>> null
>> test.d(5): Error: use '!is' instead of '!=' when comparing 
>> with null
>>
>>
>>
>> A not expert D programmer sometimes compares a double with 
>> double.nan in a wrong way:
>>
>> http://forum.dlang.org/thread/mailman.1845.1334694574.4860.digitalmars-d-learn@puremagic.com#post-jmlhfr:2428cv:241:40digitalmars.com
>>
>> because someDouble == double.nan is always false:
>>
>>
>> // Program #2
>> import std.math: isNaN;
>> void main() {
>>    double x = double.init;
>>    assert(x != double.nan);
>>    assert(x != double.init);
>>    assert(isNaN(x));
>>    assert(x is double.init);
>>    assert(x !is double.nan);
>>
>>    double y = double.nan;
>>    assert(y != double.nan);
>>    assert(y != double.init);
>>    assert(isNaN(y));
>>    assert(y !is double.init);
>>    assert(y is double.nan);
>> }
>>
>>
>>
>> I think there are three common wrong usage patterns of NaNs 
>> testing:
>> 1) Test that x is equal to/different from nan using 
>> x==FP.nan/x!=FP.nan
>> 2) Test that x is equal to/different from all NaNs using 
>> x==FP.nan/x!=FP.nan
>> 3) Test that x is equal to/different from FP.init using 
>> x==FP.init/x!=FP.init
>>
>> The case 3 is a bit less important because the programmer 
>> already knows something about FP init, but it's wrong still.
>>
>> There are other wrong usages of NaNs but they are by more 
>> expert programmers, to I don't want to catch them (example: 
>> using "is" to test if x is equal to/different from all NaNs is 
>> a bug, because there are more than one NaN. But if the 
>> programmer uses "is" I assume he/she/shi knows enough about 
>> NaNs, so this is not flagged by the compiler).
>>
>> Currently this program compiles with no errors:
>>
>>
>> // Program #3
>> void main() {
>>    float x1 = float.nan;
>>    assert(x1 == float.nan);
>>    float x2 = 0.0;
>>    assert(x2 != float.nan);
>>    float x3 = float.init;
>>    assert(x3 == float.init);
>>    float x4 = 0.0;
>>    assert(x4 != float.init);
>>
>>    double x5 = double.nan;
>>    assert(x5 == double.nan);
>>    double x6 = 0.0;
>>    assert(x6 != double.nan);
>>    double x7 = double.init;
>>    assert(x7 == double.init);
>>    double x8 = 0.0;
>>    assert(x8 != double.init);
>>
>>    real x9 = real.nan;
>>    assert(x9 == real.nan);
>>    real x10 = 0.0;
>>    assert(x10 != real.nan);
>>    real x11 = real.init;
>>    assert(x11 == real.init);
>>    real x12 = 0.0;
>>    assert(x12 != real.init);
>>
>>    enum double myNaN = double.nan;
>>    assert(myNaN == double.nan);
>> }
>>
>>
>>
>> So I propose to statically disallow comparisons of Program #3, 
>> so it generates errors similar to:
>>
>> test.d(4): Error: comparison is always false. Use 
>> 'std.math.isNaN' to test for every kind of NaN or 'is 
>> float.nan' for this specific NaN
>> test.d(6): Error: comparison is always true. Use 
>> '!std.math.isNaN' to test for every kind of NaN or '!is 
>> float.nan' for this specific NaN
>> test.d(8): Error: comparison is always false. Use 
>> 'std.math.isNaN' to test for every kind of NaN or 'is 
>> float.init' for this specicif NaN
>> ...
>>
>>
>> Opinions, improvements, votes or critics are welcome.
>>
>> Bye,
>> bearophile
>
> Good idea.
> But nothing beats this:
>
> int main() {
>     double  q;
>     q = 3.0/7.0;
>     if (q == 3.0/7.0) printf("Equal\n");
>     else printf("Not Equal\n");
>     return 0;
> }
>
> http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
> Should we disable implicit conversion "at" comparison as well?

s/double/float/

"double" version also problematic but for another case.


More information about the Digitalmars-d mailing list