From 0afb5618ce2e43d62556932b4bbf2b001cfc822b Mon Sep 17 00:00:00 2001 From: Daniel Richard G Date: Mon, 21 Oct 2013 17:29:25 -0400 Subject: [PATCH] Quash warnings for floating-point equality comparisons GCC and Clang's -Wfloat-equal warning notes that comparing floating-point values with == or != may be questionable. But the few instances of these in SolveSpace are defensibly correct (as discussed with Jonathan), so to keep folks from getting nervous that a CAD application isn't handling its floats correctly, we define an EXACT() macro inside which the -Wfloat-equal warning is disabled. This macro will also serve as a source-code annotation, like a comment but better. (The warning is only disabled for Clang, alas, because GCC is particular about where _Pragma() can be used. This isn't so bad, however, because the warning is much easier to enable on Clang [thanks to -Weverything], whereas with GCC it has to be requested explicitly.) --- graphicswin.cpp | 6 +++--- solvespace.h | 12 ++++++++++++ srf/ratpoly.cpp | 2 +- util.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/graphicswin.cpp b/graphicswin.cpp index 52e9f85..18fb422 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -355,12 +355,12 @@ void GraphicsWindow::ZoomToFit(bool includingInvisibles) { projUp. ScaledBy(-ym)); // And based on this, we calculate the scale and offset - if(dx == 0 && dy == 0) { + if(EXACT(dx == 0 && dy == 0)) { scale = 5; } else { double scalex = 1e12, scaley = 1e12; - if(dx != 0) scalex = 0.9*width /dx; - if(dy != 0) scaley = 0.9*height/dy; + if(EXACT(dx != 0)) scalex = 0.9*width /dx; + if(EXACT(dy != 0)) scaley = 0.9*height/dy; scale = min(scalex, scaley); scale = min(300, scale); diff --git a/solvespace.h b/solvespace.h index 9686b63..e16782a 100644 --- a/solvespace.h +++ b/solvespace.h @@ -7,6 +7,18 @@ #ifndef __SOLVESPACE_H #define __SOLVESPACE_H +// The few floating-point equality comparisons in SolveSpace have been +// carefully considered, so we disable the -Wfloat-equal warning for them +#ifdef __clang__ +# define EXACT(expr) \ + (_Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ + (expr) \ + _Pragma("clang diagnostic pop")) +#else +# define EXACT(expr) (expr) +#endif + // Debugging functions #define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \ if(0) *(char *)0 = 1; exit(-1); } while(0) diff --git a/srf/ratpoly.cpp b/srf/ratpoly.cpp index 547e370..66d54ba 100644 --- a/srf/ratpoly.cpp +++ b/srf/ratpoly.cpp @@ -261,7 +261,7 @@ void SBezier::MakePwlInto(SContour *sc, double chordTol) { lv.Clear(); } void SBezier::MakePwlInto(List *l, double chordTol) { - if(chordTol == 0) { + if(EXACT(chordTol == 0)) { // Use the default chord tolerance. chordTol = SS.ChordTolMm(); } diff --git a/util.cpp b/util.cpp index 89bcfb8..f5e2b12 100644 --- a/util.cpp +++ b/util.cpp @@ -479,9 +479,9 @@ bool Vector::Equals(Vector v, double tol) { } bool Vector::EqualsExactly(Vector v) { - return (x == v.x) && - (y == v.y) && - (z == v.z); + return EXACT(x == v.x && + y == v.y && + z == v.z); } Vector Vector::Plus(Vector b) { @@ -681,7 +681,7 @@ Vector Vector::ScaledBy(double v) { Vector Vector::WithMagnitude(double v) { double m = Magnitude(); - if(m == 0) { + if(EXACT(m == 0)) { // We can do a zero vector with zero magnitude, but not any other cases. if(fabs(v) > 1e-100) { dbp("Vector::WithMagnitude(%g) of zero vector!", v);