javapowered - 1 month ago 11

C++ Question

I'm using

`-Ofast`

`#include <iostream>`

#include <math.h>

static double quiet_NaN = std::numeric_limits<double>::quiet_NaN();

int main()

{

double newValue = 130000;

double curValue = quiet_NaN;

printf("newValue = %f\n", newValue);

printf("curValue = %f\n", curValue);

printf("isnan(newValue) = %d\n", isnan(newValue));

printf("isnan(curValue) = %d\n", isnan(curValue));

printf("newValue == curValue %d\n", (newValue == curValue));

printf("newValue != curValue %d\n", (newValue != curValue));

}

I've tried to run it with default flags and with -Ofast:

`$ g++ TestPointer.cpp`

$./a.out

newValue = 130000.000000

curValue = nan

isnan(newValue) = 0

isnan(curValue) = 1

newValue == curValue 0

newValue != curValue 1

$ g++ -Ofast TestPointer.cpp

$ ./a.out

newValue = 130000.000000

curValue = nan

isnan(newValue) = 0

isnan(curValue) = 1

newValue == curValue 1

newValue != curValue 0

So the result of

`!=`

`==`

`==`

`!=`

`isnan`

Is it guaranteed that

`isnan`

`-Ofast`

How correctly

`==`

`!=`

`-Ofast`

Can someone provide complete list of limitations added by

`-Ofast`

Answer

You're observing the effects of `-ffast-math`

.

From the docs:

-Ofast

Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. It turns on -ffast-math and the Fortran-specific -fno-protect-parens and -fstack-arrays.

and

-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.

and

-ffinite-math-only

Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs.

There are several gcc bug reports for this marked invalid.

Problems with -ffast-math and isnan

Additionally, comparison of strict IEEE floating points always results in false.

Checking if a double (or float) is NaN in C++

This doesn't necessarily apply for `-ffast-math`

but it explains what you show.

gcc does not describe a formal standard for how `-ffast-math`

floats work so you'll just have to work out the details empirically if you must and not assume consistency between versions of gcc. Better yet, completely avoid the combination of `NaN`

and `-ffast-math`

.