我试图在使用Visual Studio 2008编译的代码中捕获浮点异常,类似于这篇文章:Visual C++ / Weird behavior after enabling floating-point exceptions (compiler bug ?)
就在我认为我工作得很好而且被零除零被抓到并打印到命令行时,我意识到某些情况并没有被抓住。如果它是第一个发生的浮点异常,那么除零(或其他数字激励)似乎只能被捕获。我试图禁用其他异常,例如EXCEPTION_FLT_INEXACT_RESULT(真的?不是浮点数?)
无论如何,这是我尝试设置浮点寄存器和SEH,以及一些调试工具:
unsigned int cw;
unsigned int ret;
unsigned int stat1;
unsigned int stat2;
stat1 = _status87();
cw = _MCW_EM & ~_EM_INEXACT & ~_EM_UNDERFLOW & ~_EM_DENORMAL;
ret = _control87(0,cw);
stat2 = _status87();
printf("_status87() returns: 0x%x!\n",stat1);
printf("calling _control87 with inputs (0 , 0x%x)\n",cw);
printf("_control87() returned: 0x%x!\n",ret);
printf("_status87() returns: 0x%x!\n",stat2);
/*Setup the exception filter */
SetUnhandledExceptionFilter(fsim_stuff_windows_filter_function);
在我的程序开头,这段代码打印出来:
_status87() returns: 0x1!
calling _control87 with inputs (0 , 0x1c)
_control87() returned: 0x80003!
_status87() returns: 0x0!
但是,如果我把它除以零,我会看到我的fsim_stuff_windows_filter_function
被一个EXCEPTION_FLT_DIVIDE_BY_ZERO调用。
然而,在另一个案例中,零除法正在下滑。我在除以零之前检测代码以检查情况:
unsigned int ret1;
unsigned int stat1;
stat1 = _status87();
ret1 = _control87(0,0);
printf("_status87() returns: 0x%x!\n",stat1);
printf("_control87(0,0) returned: 0x%x!\n",ret1);
在我的应用程序中,此代码打印出来(我还在此处包含了对foo进行除零赋值的结果):
_status87() returns: 0x1!
calling _control87(0,0) returned:0x80013!
foo = -1.#IND00!
这里的例外从未被解雇过。我再尝试了一步,即在除以零之前重新声明_control_fp,与初始化完全相同。这是产生的印刷品,这也就是除以零之前: _status87()返回:0x1! 用输入(0,0)调用_control87 _control87(0,0)返回:0x80013! _control87(0,0x1c)返回:0x80003! _status87()返回:0x0! FPSTUFF:EXCEPTION_FLT_INVALID_OPERATION
在这里,我们可以看到异常确实存档,但这次奇怪的是ID为EXCEPTION_FLT_INVALID_OPERATION,而不是EXCEPTION_FLT_DIVIDE_BY_ZERO。
毕竟,我有几个问题: 1.有关为什么_control87的返回值在初始化后会发生变化的想法?我确定它不会被称为代码中的其他位置。初始化的结果返回值0x80003,但是当我到达被零除的位置时,该值为0x80013。此时_status87()返回值0x1。我的理论是,其他一些浮点事件(例如EXCEPTION_FLT_INEXACT_RESULT)正在设置_status87位,但由于我使用的掩码,它没有触发异常?
提前感谢您分享的任何建议或见解。