当计算结果在运行时导致NaN或inf时,我可以让gcc告诉我吗?

Jor*_*wis 18 c floating-point gcc

有没有办法告诉gcc抛出一个SIGFPE或类似的东西来响应在运行时NaN(-)inf在运行时产生的计算,就像它会被零除?

我试过了-fsignaling-nans旗帜,似乎没什么帮助.

Mar*_*son 22

几乎任何从非NaN输入产生NaN的浮点运算或数学库函数也应该发出'无效运算'浮点异常的信号; 类似地,从有限输入产生无穷大的计算通常会发出"被零除"或"溢出"浮点异常的信号.所以你想要一些方法将这些异常变成SIGFPE.

我怀疑答案将高度依赖于系统,因为浮点陷阱和标志的控制可能由平台C库而不是gcc本身提供.但这是一个适用于Linux的示例.它使用feenableexcept来自的功能fenv.h.在_GNU_SOURCE对拟申报该功能定义是必要的.

#define _GNU_SOURCE
#include <fenv.h>

int main(void) {
    double x, y, z;
    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

    x = 1e300;
    y = 1e300;
    z = x * y; /* should cause an FPE */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

需要注意的是:我认为有些设置可能会在(理论上)导致它之后的下一个浮点运算之前实际生成异常,因此有时需要进行无操作浮点运算(例如乘以1.0)以触发异常.


leg*_*s2k 5

在 MinGW 4.8.1(Win32 的 GCC)上,我看到feenableexcept没有定义。解决方法是使用 Win32 平台,_controlfp因此:

#undef __STRICT_ANSI__ // _controlfp is a non-standard function documented in MSDN
#include <float.h>
#include <stdio.h>

int main()
{
   _clearfp();
   unsigned unused_current_word = 0;
   // clearing the bits unmasks (throws) the exception
   _controlfp_s(&unused_current_word, 0, _EM_OVERFLOW | _EM_ZERODIVIDE);  // _controlfp_s is the secure version of _controlfp

   float num = 1.0f, den = 0.0f;
   float quo = num / den;
   printf("%.8f\n", quo);    // the control should never reach here, due to the exception thrown above
}
Run Code Online (Sandbox Code Playgroud)