在C中捕获浮点溢出

时间:2017-07-24 19:06:56

标签: c exception-handling floating-point

我试图在C中捕获浮点溢出。这是我尝试过的

#define _GNU_SOURCE

#include <fenv.h>
#include <signal.h>
#include <stdio.h>

void catch_overflow (int sig) {   
  printf ("caught division by zero\n");   
  signal (sig, catch_overflow); 
}


int main(void) {   
  feenableexcept(FE_DIVBYZERO);   
  signal (FE_DIVBYZERO, catch_overflow);


  float a = 1., b = 0.;   float c = a/b;   return 0; }

我希望看到&#34;被零划分为&#34;消息,但我只收到核心转储消息,&#34;浮点异常(核心转储)&#34;。我怎样才能修改程序,以便将被捕获的除法归零[&#34;消息?

感谢。

1 个答案:

答案 0 :(得分:0)

浮点异常以机器和操作系统相关的方式转换为某些信令方法。但是没有这种方法允许混合不同的恒定空间,如FE_xxx和SIGxxx。使用FE_DIVBYZERO用于signal(),你真的抓住了SIGILL这不是因为浮点错误而生成的(因为你没有指定操作系统,我可以自由选择任何 - 在我的情况下是Linux)。 / p>

对于您的程序,我已经使这个异常在Linux下工作,并进行了两处更改:

  1. 设置要处理SIGFPE的信号编号。

  2. a, b, c声明为volatile(阻止编译器在编译时将c计算为INF)。

  3. 在此之后,该程序陷入了永恒的循环打印,并且被零和#34;因为此类错误的信号处理程序将执行恢复到同一命令。你应该仔细考虑如何解决这些错误,而不会使错误的指令永恒。例如,您可以使用longjmp退出已安装的异常处理程序的信号处理程序。

    而且,您仍然应该查阅目标操作系统手册,了解如何捕获FP错误。

    (已经在主要部分的评论中对此进行了描述 - 但我考虑形成一个明确的答案。)