使用 <csignal> 处理除以零会导致意外行为

Handling division by zero with <csignal> results in unexpected behaviour

我试图处理整数除以零(请不要判断,我被告知我必须使用 <csignal> 库,我不能只使用 if 语句),但我需要确保程序将保持 运行(即使这是一个非常糟糕的做法),而不是崩溃或关闭。奇怪的是程序应该只处理除以零但应该退出所有其他类型的 SIGFPE.

旁注:现在,我不知道为什么他们在引用整数时使用 FPUFEFPE 这样的名称 "exceptions"(或者我应该说中断),因为标准明确表示除法浮点数应该 return infnan 0 / 0(如果我错了告诉我)。

无论如何,我写这个测试代码是为了在实际实施之前更好地理解我需要做什么。我知道,将 x 作为全局变量很奇怪,但如果我不重置它,它会无缘无故地永远调用 handle....

#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;
}

如您所见,我使用 FPE_INTDIV 来排除所有其他类型的异常,但它不起作用。 最终我发现 FPE_INTDIV7 的符号常量(这是 vs-code 的智能感知告诉我的),如果我要打印 s 的值,那将是 8.我发现,奇怪的是,8FPE_INTOVF 的值,文档指出它是专门为整数溢出设计的。

既然有整数除法的符号,为什么还要用溢出的符号值来除法呢?我错过了什么?有人弄乱了库中的值吗?我使用了错误的宏吗?

我还应该提一下,这段代码可以用 clang++g++ 编译,但是在 Windows 计算机上编译时cl,它告诉我 FPE_INTDIV.

没有宏

我如何确定自己在做什么并编写有效的跨平台解决方案?

我已经觉得自己像个白痴了。

defined 为:

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.

没有理由专门为它贴上标签FPE,但这类标签可能会以不可预测的方式演变。我不会读太多。

这些 signals 是 POSIX 标准的一部分,可能未在 Windows 中得到完全支持或实施。 Windows 这些支持设施的实施在许多领域都缺乏,例如如何 fork() 不受支持。