Search code examples
cnaninfinitymath.h

Disable exception with Infinity and NaN


I have a huge project (not built by me) that is allowed to have Infinity and NaN values. Although it's allowed, it is not desirable. I read that these values are generated by these kind of operations:

1/0 = ∞
log (0) = -∞
sqrt (-1) = NaN

and, beside this, when they're reached, a FP Exception should be thrown.

If my project allows having operations with NaN and Infinity, I thought that SIGFPE would be handled somewhere, but I searched in the entire project and could not find it.

Is there another way to disable this exception? My goal is to be able to detect the first occurrence of these kind of values.

EDIT: I'm using Windows and I intend to enable the signal, but before I enable, I'd like to understand if it got disabled.


Solution

  • I think you are not going to have the problems you are talking about. By default, no FP exception are raised. From the Windows documentation:

    By default, the system has all FP exceptions turned off. Therefore, computations result in NAN or INFINITY, rather than an exception. Before you can trap floating-point (FP) exceptions using structured exception handling, you must call the _controlfp_s C run-time library function to turn on all possible FP exceptions. To trap only particular exceptions, use only the flags that correspond to the exceptions to be trapped. Note that any handler for FP errors should call _clearfp as its first FP instruction. This function clears floating-point exceptions.

    The same is true also for GCC, where the documentation says:

    When exceptions occur (when exceptions are raised, in the language of the standard), one of two things can happen. By default the exception is simply noted in the floating-point status word, and the program continues as if nothing had happened. The operation produces a default value, which depends on the exception [...]). Your program can check the status word to find out which exceptions happened.

    To enable exceptions (that will stop the execution of your program) in your Windows environment, you may try something like

    #include <float.h>
    
    int main() {
        _clearfp();
        unsigned int current_word = 0;
        _controlfp_s(&current_word, ~_EM_ZERODIVIDE, _MCW_EM);
        double div = 0.;
        double f = 1. / div;
    }
    

    For non blocking solutions, try using fenv.h as explained here on cppreference.com.