gpt4 book ai didi

visual-c++ - Visual C++/启用浮点异常后的奇怪行为(编译器错误?)

转载 作者:行者123 更新时间:2023-12-04 06:42:31 27 4
gpt4 key购买 nike

我正在努力寻找一种可靠的方法来捕获 Visual Studio(2005 或 2008)下的浮点异常。默认情况下,visual studio下,浮点异常是不会被捕获的,而且是比较难捕获的(主要是大部分都是硬件信号,需要翻译成异常)

这是我所做的:
- 开启 SEH 异常处理
(属性/代码生成/启用 C++ 异常:是,SEH 异常)
- 使用 _controlfp 激活浮点异常

我现在确实捕获了异常(如下面的示例所示,其中一个简单的除以零异常)。
然而,一旦我发现这个异常,程序似乎已经不可修复地损坏了(因为简单的浮点初始化以及 std::cout 将不起作用!)。

我已经构建了一个简单的演示程序来展示这种相当奇怪的行为。

注意:此行为已在多台计算机上重现。

#include "stdafx.h"
#include <math.h>

#include <float.h>
#include <iostream>


using namespace std;


//cf http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html#x86_FP
//cf also the "Numerical Recipes" book, which gives the same advice
//on how to activate fp exceptions
void TurnOnFloatingExceptions()
{
unsigned int cw;
// Note : same result with controlfp
cw = _control87(0,0) & MCW_EM;
cw &= ~(_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW);
_control87(cw,MCW_EM);

}

//Simple check to ensure that floating points math are still working
void CheckFloats()
{
try
{
// this simple initialization might break
//after a float exception!
double k = 3.;
std::cout << "CheckFloatingPointStatus ok : k=" << k << std::endl;
}
catch (...)
{
std::cout << " CheckFloatingPointStatus ==> not OK !" << std::endl;
}
}


void TestFloatDivideByZero()
{
CheckFloats();
try
{
double a = 5.;
double b = 0.;
double c = a / b; //float divide by zero
std::cout << "c=" << c << std::endl;
}
// this catch will only by active:
// - if TurnOnFloatingExceptions() is activated
// and
// - if /EHa options is activated
// (<=> properties / code generation / Enable C++ Exceptions : Yes with SEH Exceptions)
catch(...)
{
// Case 1 : if you enable floating points exceptions ((/fp:except)
// (properties / code generation / Enable floting point exceptions)
// the following line will not be displayed to the console!
std::cout <<"Caught unqualified division by zero" << std::endl;
}
//Case 2 : if you do not enable floating points exceptions!
//the following test will fail!
CheckFloats();
}


int _tmain(int argc, _TCHAR* argv[])
{
TurnOnFloatingExceptions();
TestFloatDivideByZero();
std::cout << "Press enter to continue";//Beware, this line will not show to the console if you enable floating points exceptions!
getchar();
}

有没有人知道可以做些什么来纠正这种情况?
提前谢谢了!

最佳答案

捕获浮点异常时,必须清除状态字中的 FPU 异常标志。调用 _clearfp()。

考虑使用 _set_se_translator() 编写一个异常过滤器,将硬件异常转换为 C++ 异常。一定要有选择性,只翻译 FPU 异常。

关于visual-c++ - Visual C++/启用浮点异常后的奇怪行为(编译器错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4282217/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com