Reputation: 22922
I've been debugging a C++ application in VS2015 and found that a number of my double variables were ending up a NaN following a divide by zero. While this is reasonable, I have floating point exceptions enabled (/fp:except) so I would have expected this to raise an exception. Looking at the MS help page, it doesn't list what causes a floating point exception. According to this answer to a related question, divide by zero is a floating point exception. This is not the case, i.e. the following test program with /fp:except enabled
int main()
{
try
{
double x = 1;
double y = 0;
double z = x / y;
printf("%f\n", z);
return 0;
}
catch (...)
{
printf("Exception!\n");
return 0;
}
}
displays "inf". Should this raise a floating point exception?
Edit: Checked the exceptions were enabled in the debugger and get the same result regardless
Edit2: Further reading here on IEE 754 suggests to me that with floating point exceptions enabled I should be getting an exception. A comment to the previously linked question however states 'The name "floating point exception" is a historical misnomer. Floating point division by zero is well-defined (per Annex F/IEEE754) and does not produce any signal.'
Upvotes: 1
Views: 544
Reputation: 15366
Floating point exceptions are not the same as C++ exceptions. They either have to be checked using std::fetestexcept()
(below) or trapped (SIGFPE
). Using traps requires calling _controlfp()
in MSVC and feenableexcept()
in GCC.
#include <iostream>
#include <cfenv>
#include <stdexcept>
// MSVC specific, see
// https://learn.microsoft.com/en-us/cpp/preprocessor/fenv-access?view=msvc-160
#pragma fenv_access (on)
int main() {
std::feclearexcept(FE_ALL_EXCEPT);
double y = 0.0;
double result{};
result = 1 / y;
std::cout << result << std::endl;
if (std::fetestexcept(FE_ALL_EXCEPT) & FE_DIVBYZERO) {
throw std::runtime_error("Division by zero");
}
return 0;
}
There are more examples of this in the SEI CERT C Coding Standard: https://wiki.sei.cmu.edu/confluence/display/c/FLP03-C.+Detect+and+handle+floating-point+errors.
Note that division by zero is undefined; it's not required to signal, but C and C++ implementations that define __STDC_IEC_559__
"shall" signal.
Upvotes: 2