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.)
This commit is contained in:
Daniel Richard G 2013-10-21 17:29:25 -04:00
parent 8bc322eb47
commit 0afb5618ce
4 changed files with 20 additions and 8 deletions

View File

@ -355,12 +355,12 @@ void GraphicsWindow::ZoomToFit(bool includingInvisibles) {
projUp. ScaledBy(-ym)); projUp. ScaledBy(-ym));
// And based on this, we calculate the scale and offset // And based on this, we calculate the scale and offset
if(dx == 0 && dy == 0) { if(EXACT(dx == 0 && dy == 0)) {
scale = 5; scale = 5;
} else { } else {
double scalex = 1e12, scaley = 1e12; double scalex = 1e12, scaley = 1e12;
if(dx != 0) scalex = 0.9*width /dx; if(EXACT(dx != 0)) scalex = 0.9*width /dx;
if(dy != 0) scaley = 0.9*height/dy; if(EXACT(dy != 0)) scaley = 0.9*height/dy;
scale = min(scalex, scaley); scale = min(scalex, scaley);
scale = min(300, scale); scale = min(300, scale);

View File

@ -7,6 +7,18 @@
#ifndef __SOLVESPACE_H #ifndef __SOLVESPACE_H
#define __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 // Debugging functions
#define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \ #define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \
if(0) *(char *)0 = 1; exit(-1); } while(0) if(0) *(char *)0 = 1; exit(-1); } while(0)

View File

@ -261,7 +261,7 @@ void SBezier::MakePwlInto(SContour *sc, double chordTol) {
lv.Clear(); lv.Clear();
} }
void SBezier::MakePwlInto(List<Vector> *l, double chordTol) { void SBezier::MakePwlInto(List<Vector> *l, double chordTol) {
if(chordTol == 0) { if(EXACT(chordTol == 0)) {
// Use the default chord tolerance. // Use the default chord tolerance.
chordTol = SS.ChordTolMm(); chordTol = SS.ChordTolMm();
} }

View File

@ -479,9 +479,9 @@ bool Vector::Equals(Vector v, double tol) {
} }
bool Vector::EqualsExactly(Vector v) { bool Vector::EqualsExactly(Vector v) {
return (x == v.x) && return EXACT(x == v.x &&
(y == v.y) && y == v.y &&
(z == v.z); z == v.z);
} }
Vector Vector::Plus(Vector b) { Vector Vector::Plus(Vector b) {
@ -681,7 +681,7 @@ Vector Vector::ScaledBy(double v) {
Vector Vector::WithMagnitude(double v) { Vector Vector::WithMagnitude(double v) {
double m = Magnitude(); double m = Magnitude();
if(m == 0) { if(EXACT(m == 0)) {
// We can do a zero vector with zero magnitude, but not any other cases. // We can do a zero vector with zero magnitude, but not any other cases.
if(fabs(v) > 1e-100) { if(fabs(v) > 1e-100) {
dbp("Vector::WithMagnitude(%g) of zero vector!", v); dbp("Vector::WithMagnitude(%g) of zero vector!", v);