有没有办法告诉gcc抛出一个SIGFPE或者类似的东西来响应在运行时产生NaN
或(-)inf
的计算,就像它会被零除?
我已经尝试了-fsignaling-nans
标志,这似乎没什么帮助。
答案 0 :(得分:21)
几乎任何从非NaN输入产生NaN的浮点运算或数学库函数也应该发出'无效操作'浮点异常的信号;类似地,从有限输入产生无穷大的计算通常会发出“被零除”或“溢出”浮点异常的信号。因此,您需要一些方法将这些异常转换为SIGFPE。
我怀疑答案将高度依赖于系统,因为浮点陷阱和标志的控制可能由平台C库而不是gcc本身提供。但这是一个适用于Linux的示例。它使用feenableexcept
中的fenv.h
函数。 _GNU_SOURCE
define是声明此函数所必需的。
#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;
}
需要注意的是:我认为有些设置可能会在下一个浮点运算(理论上)应该导致它之后实际生成异常,所以你有时需要一个无操作的浮点运算(例如乘以1.0)来触发异常。
答案 1 :(得分:4)
在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
}