Code (t1.c):
#include <stdio.h>
#include <float.h>
#include <fenv.h>
#if _MSC_VER
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
void print_fpe()
{
int fpe = fetestexcept(FE_ALL_EXCEPT);
printf("current exceptions raised:");
if (fpe & FE_DIVBYZERO) printf(" FE_DIVBYZERO");
if (fpe & FE_INEXACT) printf(" FE_INEXACT");
if (fpe & FE_INVALID) printf(" FE_INVALID");
if (fpe & FE_OVERFLOW) printf(" FE_OVERFLOW");
if (fpe & FE_UNDERFLOW) printf(" FE_UNDERFLOW");
if ((fpe & FE_ALL_EXCEPT)==0) printf(" none");
}
volatile double d = DBL_MAX;
volatile float f = FLT_MAX;
volatile signed long long ll;
volatile signed long l;
volatile signed int i;
volatile signed short s;
volatile signed char c;
volatile unsigned long long ull;
volatile unsigned long ul;
volatile unsigned int ui;
volatile unsigned short us;
volatile unsigned char uc;
#define TEST(dst, type, src) \
feclearexcept(FE_ALL_EXCEPT); \
dst = (type)(src); \
print_fpe(); \
printf(" line %u\n", __LINE__);
int main(void)
{
TEST(ll, signed long long, d);
TEST(l, signed long, d);
TEST(i, signed int, d);
TEST(s, signed short, d);
TEST(c, signed char, d);
TEST(ll, signed long long, f);
TEST(l, signed long, f);
TEST(i, signed int, f);
TEST(s, signed short, f);
TEST(c, signed char, f);
TEST(ull, unsigned long long, d); // line 55
TEST(ul, unsigned long, d);
TEST(ui, unsigned int, d);
TEST(us, unsigned short, d);
TEST(uc, unsigned char, d);
TEST(ull, unsigned long long, f); // line 60
TEST(ul, unsigned long, f);
TEST(ui, unsigned int, f);
TEST(us, unsigned short, f);
TEST(uc, unsigned char, f);
return 0;
}
Invocations and results:
$ cl t1.c && t1
current exceptions raised: FE_INVALID line 45
current exceptions raised: FE_INVALID line 46
current exceptions raised: FE_INVALID line 47
current exceptions raised: FE_INVALID line 48
current exceptions raised: FE_INVALID line 49
current exceptions raised: FE_INVALID line 50
current exceptions raised: FE_INVALID line 51
current exceptions raised: FE_INVALID line 52
current exceptions raised: FE_INVALID line 53
current exceptions raised: FE_INVALID line 54
current exceptions raised: FE_INEXACT FE_INVALID line 55
current exceptions raised: FE_INVALID line 56
current exceptions raised: FE_INVALID line 57
current exceptions raised: FE_INVALID line 58
current exceptions raised: FE_INVALID line 59
current exceptions raised: FE_INEXACT FE_INVALID line 60
current exceptions raised: FE_INVALID line 61
current exceptions raised: FE_INVALID line 62
current exceptions raised: FE_INVALID line 63
current exceptions raised: FE_INVALID line 64
$ clang t1.c && ./a.exe
t1.c:8:14: warning: pragma STDC FENV_ACCESS ON is not supported, ignoring pragma [-Wunknown-pragmas]
#pragma STDC FENV_ACCESS ON
^
1 warning generated.
current exceptions raised: FE_INVALID line 45
current exceptions raised: FE_INVALID line 46
current exceptions raised: FE_INVALID line 47
current exceptions raised: FE_INVALID line 48
current exceptions raised: FE_INVALID line 49
current exceptions raised: FE_INVALID line 50
current exceptions raised: FE_INVALID line 51
current exceptions raised: FE_INVALID line 52
current exceptions raised: FE_INVALID line 53
current exceptions raised: FE_INVALID line 54
current exceptions raised: FE_INEXACT FE_INVALID line 55
current exceptions raised: FE_INEXACT FE_INVALID line 56
current exceptions raised: FE_INVALID line 57
current exceptions raised: FE_INVALID line 58
current exceptions raised: FE_INVALID line 59
current exceptions raised: FE_INEXACT FE_INVALID line 60
current exceptions raised: FE_INEXACT FE_INVALID line 61
current exceptions raised: FE_INVALID line 62
current exceptions raised: FE_INVALID line 63
current exceptions raised: FE_INVALID line 64
$ gcc t1.c && ./a.exe
current exceptions raised: FE_INVALID line 45
current exceptions raised: FE_INVALID line 46
current exceptions raised: FE_INVALID line 47
current exceptions raised: FE_INVALID line 48
current exceptions raised: FE_INVALID line 49
current exceptions raised: FE_INVALID line 50
current exceptions raised: FE_INVALID line 51
current exceptions raised: FE_INVALID line 52
current exceptions raised: FE_INVALID line 53
current exceptions raised: FE_INVALID line 54
current exceptions raised: FE_INEXACT FE_INVALID line 55
current exceptions raised: FE_INEXACT FE_INVALID line 56
current exceptions raised: FE_INVALID line 57
current exceptions raised: FE_INVALID line 58
current exceptions raised: FE_INVALID line 59
current exceptions raised: FE_INEXACT FE_INVALID line 60
current exceptions raised: FE_INEXACT FE_INVALID line 61
current exceptions raised: FE_INVALID line 62
current exceptions raised: FE_INVALID line 63
current exceptions raised: FE_INVALID line 64
Question: why conversion (unsigned long long)DBL_MAX
(or FLT_MAX
) causes raising of FE_INEXACT
as well?