I was trying to handle the integer division by zero (please don't judge, I was told I had to use <csignal>
lib and I couldn't just use an if statement), but I needed to make sure the program would keep running (even though it's a very bad practice), instead of crashing or closing. The weird part is that the program should only handle division by zero but should exit for every other type of SIGFPE
.
SideNote: Now, I have no idea why they use names like FPU
or FE
or FPE
when referring to integer "exceptions" (or I should say interrupts) since the standard says clearly that dividing a floating point number should return either inf
or nan
for 0 / 0
(tell me if I'm wrong).
Anyway, I wrote this test code so I could better understand what I needed to do before the actual implementation. I know, it's weird to have x
as a global variable but if I don't reset it, it will keep calling handle
for no reason like forever....
#include <iostream>
#include <csignal>
using namespace std;
int x = 0;
void handle(int s);
int main(int argc, char * argv[]) {
signal(SIGFPE, handle);
cout << "Insert 0: ";
cin >> x; // here I would input 0, so the program can compile
x = 5 / x;
cout << "X: " << x << endl;
return 0;
}
void handle(int s) {
if (s != FPE_INTDIV) exit(1);
cout << "sig: " << s << endl;
x = 1;
}
As you can see I used FPE_INTDIV
to rule out every other type of exceptions, but it doesn't work.
Eventually I discovered that FPE_INTDIV
is a symbolic constant for 7
(that's what vs-code's intellisense tells me) and if I were to print the value of s
, that would be 8
. I discovered that, strangely enough, 8
is the value for FPE_INTOVF
on which the documentation states that it's specifically designed for integer overflows.
Why on earth is the symbolic value for overflows used for integer division if there is a symbolic for integer division? What am I missing? Did someone mess up the values in the library? Am I using the wrong macros?
I should also mention, this code compiles fine with clang++ and g++ but when compiled on a Windows computer with cl, it tells me there's no macro for FPE_INTDIV
.
How can I be sure of what I'm doing and write a cross platform solution that works?
I already feel like an idiot.
It's defined as:
The
SIGFPE
signal reports a fatal arithmetic error. Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow. If a program stores integer data in a location which is then used in a floating-point operation, this often causes an “invalid operation” exception, because the processor cannot recognize the data as a floating-point number.
There's no reason for it to be labelled specifically FPE
but these sorts of labels can evolve in unpredictable ways. I wouldn't read too much into it.
These signals are part of the POSIX standard and may not be fully supported or implemented in Windows. The Windows implementation of these support facilities is lacking in a number of areas, like how fork()
is unsupported.