I've run into an issue with floating-point comparisons. When comparing a value with NaN using the <
operator, I expect the FE_INVALID
flag to be set. The <
operator should raise the flag according to the C11 standard (and also according to IEEE-754):
The
isless
macro determines whether its first argument is less than its second argument. The value ofisless(x, y)
is always equal to(x) < (y)
; however, unlike(x) < (y)
,isless(x, y)
does not raise the "invalid" floating-point exception whenx
andy
are unordered.
Here is an example program to reproduce my issue:
#include <stdio.h>
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
int main()
{
volatile float a = 12.0f;
volatile float b = NAN;
volatile int c;
feclearexcept(FE_ALL_EXCEPT);
c = (a < b);
if (fetestexcept(FE_INVALID))
printf("FE_INVALID\n");
else
printf("Not invalid\n");
return 0;
}
On my machine (Linux, march=broadwell
) it returns "Not invalid".
I compiled it using GCC v7.2.0, using the -std=c11
option (not using it didn't change anything in the result). The emitted x86 instruction is UCOMISS
which is only raising exceptions for signalling NaNs - I would expect to see COMISS
as that would raise the exception on all NaN comparisons, as NaNs are unordered no matter whether they're signalling or not.
Did I make a mistake in my code or forget some compiler option to make the behavior IEEE-compliant? Could it be a bug (or performance optimization) in the compiler to ignore the need to raise an exception here?
c
is 0 although I commented out the pramga because it is not recognised. – Photoemissionfeclearexcept(FE_ALL_EXCEPT);
returns zero. – Saltandpepper__STDC_IEC_559__
. "An implementation that defines _ STDC_IEC_559 _ shall conform to the specifications in this annex." (IEEE-compliant? ) If__STDC_IEC_559__
is not defined, code is not specified to behave as desired. Only mistake then is an incorrect expectation. – Saltandpepperfeclearexcept
, it returns 0. Also very good point about IEEE-compliance. (Un)fortunately,__STDC_IEC_559__
is defined, so the issue lies somewhere else.. – Lees