[Issue 9668] New: Disallow (dis)equality with FP.nan/FP.init literals
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Mar 8 11:50:07 PST 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9668
Summary: Disallow (dis)equality with FP.nan/FP.init literals
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nobody at puremagic.com
ReportedBy: bearophile_hugs at eml.cc
--- Comment #0 from bearophile_hugs at eml.cc 2013-03-08 11:50:05 PST ---
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
Not expert D programmers sometime compare 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 many bitwise-different
NaNs. 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.
See discussion thread, this idea was generally liked:
http://forum.dlang.org/thread/undjpdewiqmghmhndedw@forum.dlang.org
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list