I am trying to use signaling_nan() to automatically throw an exception if a variable whose value will be set post-initialization, is used before being set.
I have tried using the floating point exception functionalities via fenv.h, however that solution needs an if test for FE_INVALID, which I would like to avoid.
I am including a reduced example code below. In the code I have a class A with a member double x, which I initialize to a signaling_nan() in the constructor. The class also includes a function divide_by_x, which divides the argument passed in by the class member x. I create an object A a1, and call a1.divide_by_x(10.0). I expected the program to thrown an exception, however it proceeds and returns nan as a value for the divide_by_x function call.
In the example code I have included an if test for the FE_INVALID floating point exception at the end of the program, and its output changes along expected lines if x is initialized with a quiet_nan() [Not invalid] vs signaling_nan() [FE_INVALID]. This indicates that the signaling_nan() is indeed generating a floating point exception, but the program continues executing.
#include<iostream>
#include <utility>
#include <limits>
#include <float.h>
#include <signal.h>
#include <fenv.h>
using namespace std;
class A
{
public:
// Constructor
A():x(std::numeric_limits<double>::signaling_NaN()){}
//A():x(std::numeric_limits<double>::quiet_NaN()){}
// Set x
void set_x(double x_value) { x = x_value; }
// Divide number by x
double divide_by_x(double other_number)
{
double result = other_number/x;
return result;
}
// Member
double x;
};
int main(void)
{
feclearexcept(FE_ALL_EXCEPT);
A a1;
double before_setting_x;
before_setting_x = a1.divide_by_x(10.0);
if (fetestexcept(FE_INVALID))
printf("FE_INVALID\n");
else
printf("Not invalid\n");
return 0;
}
Output with x initialized with signaling_nan():
FE_INVALID
Output with x initialized with quiet_nan():
Not invalid
So, there's a lot of ways to go about this problem:
Custom Classes, Which Check for FPE in Operations
The simplest way is just to write a wrapper class, that checks for floating-point exceptions, and then never have to deal with it later, with all the numeric operations built-in.
feenableexcept
Another approach is to use
feenableexceptat the start of the program:This will produce a SIGFPE if an invalid floating-point exception occurs. You can also use a GCC extension so this automatically occurs before
main.You can also use this with signal handlers.
Bespoke Assembly
I highly recommend not doing this, since it won't be portable (even on x86, since it would differ for x87 FPUs vs. newer x86 CPUs with SSE2. However, you could try to use inline assembly to check for floating-point exceptions, even though this is likely a very bad idea. For example, dealing with the x87 FPU status register is detailed here.