可能な浮動小数点オーバーフローを持つコードがありますが、関数の引数を調べて管理することはできません。 _matherr
を定義し、その内部から例外をスローして、呼び出し元に問題を管理する機会を与える必要があります。リリースビルドで_matherrが呼び出されない(C++ Builder 2007)
奇妙なことがあります:デバッグビルドでは、_matherrは想定どおりに呼び出されますが、リリースでは呼び出されません。私はCodeGear C++ Builder 2007を使用しています.MSVC 2010では、ハンドラはうまく動作しますが、アプリケーション全体にVCL機能が必要です。グーグルでは、_matherr
に関するメッセージは何も表示されません(ドキュメンテーションで知られています)。
私の質問は、_matherr
がリリースで動作しない理由は何ですか?
// 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例外をマスクしない制御語を使用していると思っていました。そして、彼らはFP例外を 'EMathError'例外に変換するSEHハンドラを持っています。私はいつも、C++ BuilderはDelphiと同じようにしていたと考えていました。そうじゃないの? –
@DavidHeffernanそうではありません。少なくとも、 "EMathError"や "..."をキャッチしても、標準の "pow:OVERFLOW error"メッセージボックスは表示されません(__tryingや__exceptingも役に立ちません)。 '_matherr'のドキュメントはEMathErrorについて全く言及していません。' _matherr'はデバッグ(とMSVCの下で)で期待どおりに動作します。そのため、 '_matherr'を使うべきです。 –
さて、私は、MSVCがC++ Builderが何をしているかに大きな影響を与えているとは考えていません。どの8087コントロールワードがあなたのアプリで使用されていますか?デバッグとリリースビルドでは違いますか? –