禁用Infinity和NaN的异常处理

3

我有一个庞大的项目(不是由我建立的),允许具有InfinityNaN值。虽然允许这样做,但并不理想。我阅读到,这些值是由以下类型的操作生成的:

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

此外,当它们被达到时,应抛出FP Exception
如果我的项目允许使用NaNInfinity进行操作,我认为SIGFPE将在某个地方被处理,但我搜索整个项目却找不到它。
是否有另一种方法可以禁用此异常?我的目标是能够检测到这些值的第一次出现。
编辑: 我正在使用Windows,并且打算启用该信号,但在启用之前,我想了解它是否已被禁用。

有没有其他方法可以禁用这个异常?我的目标是能够检测到这些值的第一次出现。这不意味着您实际上想要启用此异常吗? - user694733
@user694733 是的,启用它会很好,但首先我想了解如何禁用它。 - João Paulo
2
我不确定我是否正确理解了您的意思:您想要抛出SIGFPE吗?我正在使用GCC,在我的安装中,它不会被抛出,并且我还没有找到一种方法来启用它。 - GermanNerd
1
你正在运行什么操作系统? - newbie
1
从您提到的GCC文档中可以看到:当异常发生时(在标准语言中称为引发异常),会发生以下两种情况。默认情况下,异常仅在浮点状态字中被记录,并且程序将继续执行,就好像什么都没有发生一样。操作会产生一个默认值,该值取决于异常[...]。您的程序可以检查状态字以找出发生了哪些异常。 - Giovanni Cerretani
显示剩余4条评论
1个回答

3
我认为你不会遇到你所说的问题。默认情况下,不会引发任何FP异常。来自Windows documentation

默认情况下,系统关闭所有FP异常。因此,计算结果为NAN或INFINITY,而不是异常。在使用结构化异常处理捕获浮点(FP)异常之前,必须调用_controlfp_s C运行时库函数以打开所有可能的FP异常。要仅捕获特定异常,请仅使用对应于要捕获的异常的标志。请注意,任何FP错误处理程序都应将_clearfp作为其第一个FP指令调用。此函数清除浮点异常。

同样适用于GCC,documentation中也是如此:
当异常发生时(在标准语言中,当抛出异常时),会发生两种情况之一。默认情况下,异常只是在浮点状态字中被记录,并且程序将继续进行,就好像什么都没有发生一样。该操作会产生一个默认值,该默认值取决于异常[...]。您的程序可以检查状态字以找出发生了哪些异常。
要在Windows环境中启用异常(将停止程序的执行),您可以尝试以下操作:
#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;
}

对于非阻塞解决方案,可以尝试使用 fenv.h,如在 cppreference.com 这里 所述。


也许我应该使用 feraiseexcept 来启用? - João Paulo
我不明白你是想启用还是禁用异常。 - Giovanni Cerretani
现在我理解了上下文,我想要启用。 - João Paulo
2
请注意,纯C的VC支持使用__try {...} __except(){...}语句块进行SEH(结构化异常处理)。这样一来,程序就不会意外终止(但是它不会告诉您异常发生的位置。如果想了解异常位置,请去掉SEH并在调试器中运行程序)。 - Paul Ogilvie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接