2
我有一个可能的浮点溢出代码,它不能通过检查函数的参数来管理。我必须定义_matherr
并在其中抛出异常,以便给调用者管理问题的机会。_matherr不会在发布版本中调用(C++ Builder 2007)
有一些奇怪的地方:在调试版本中,_matherr被调用为假定的,但不是在Release中。我使用CodeGear C++ Builder 2007.在MSVC 2010下,处理程序工作正常,但我需要整个应用程序的VCL功能。谷歌搜索只给出了关于_matherr
不能在DLL中工作的消息(从文档中可以知道)。
而我的问题是:_matherr
不能在Release中工作的原因是什么?
// One of the methods with overflows.
double DoubleExponential::F(double x) const
{
try
{
double y=pow(fabs(x),a);
return 0.5 + sign(x)*G(y,1/a)/(2*G(1/a));
}
catch(PowExpOverflow)
{
return 0.5;
}
}
// Exception.
struct PowExpOverflow {};
int _matherr (struct _exception *a){
Application->MessageBox("Inside custom _matherr", "", MB_OK);
if (a->type == OVERFLOW)
if (!strcmp(a->name,"pow") ||
!strcmp(a->name,"powl") ||
!strcmp(a->name,"exp") ||
!strcmp(a->name,"expl"))
{
throw PowExpOverflow();
}
return 0;
}
我觉得这有点奇怪。我认为所有的Embarcadero工具都使用了一个没有掩盖FP异常的控制字。然后他们有一个SEH处理程序将FP异常转换为'EMathError'异常。我一直认为C++ Builder的做法与Delphi相同。情况并非如此吗? – 2012-01-13 13:09:40
@DavidHeffernan似乎没有。至少,捕捉'EMathError'或'...'不会阻止标准的“pow:OVERFLOW错误”消息框出现(__trying和__excepting也不会帮助)。关于'_matherr'的文档根本没有提到EMathError,'_matherr'在调试(和MSVC下)中按预期工作,这就是我认为应该使用_matherr的原因。 – 2012-01-13 16:37:12
那么,我不会认为MSVC对C++ Builder的功能有什么影响。什么8087控制字在您的应用程序中使用?它在调试和发布构建方面有所不同吗? – 2012-01-13 17:01:13