LiraNuna LiraNuna - 18 days ago 5
C++ Question

Negative NaN is not a NaN?

While writing some test cases, and some of the tests check for the result of a NaN.

I tried using

std::isnan
but the assert failes:

Assertion `std::isnan(x)' failed.


After printing the value of
x
, it turned out it's negative NaN (
-nan
) which is totally acceptable in my case.

After trying to use the fact that
NaN != NaN
and using
assert(x == x)
, the compiler does me a 'favor' and optimises the assert away.

Making my own
isNaN
function is being optimised away as well.

How can I check for both equality of NaN and -NaN?

Answer

This is embarrassing.

The reason the compiler (GCC in this case) was optimising away the comparison and isnan returned false was because someone in my team had turned on -ffast-math.

From the docs:

-ffast-math
    Sets -fno-math-errno, -funsafe-math-optimizations,
    -fno-trapping-math, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and fcx-limited-range.

    This option causes the preprocessor macro __FAST_MATH__ to be defined.

    This option should never be turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions. 

Notice the ending sentence - -ffast-math is unsafe.