2012-01-13 5 views
2

可能な浮動小数点オーバーフローを持つコードがありますが、関数の引数を調べて管理することはできません。 _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; 
} 
+1

これはちょっと奇妙です。私はEmbarcaderoのすべてのツールがFP例外をマスクしない制御語を使用していると思っていました。そして、彼らはFP例外を 'EMathError'例外に変換するSEHハンドラを持っています。私はいつも、C++ BuilderはDelphiと同じようにしていたと考えていました。そうじゃないの? –

+0

@DavidHeffernanそうではありません。少なくとも、 "EMathError"や "..."をキャッチしても、標準の "pow:OVERFLOW error"メッセージボックスは表示されません(__tryingや__exceptingも役に立ちません)。 '_matherr'のドキュメントはEMathErrorについて全く言及していません。' _matherr'はデバッグ(とMSVCの下で)で期待どおりに動作します。そのため、 '_matherr'を使うべきです。 –

+0

さて、私は、MSVCがC++ Builderが何をしているかに大きな影響を与えているとは考えていません。どの8087コントロールワードがあなたのアプリで使用されていますか?デバッグとリリースビルドでは違いますか? –

答えて

1

問題は、リリースビルド(description)で使用する動的RTLのバグが原因です。このバグは、私が使用しているIDEのバージョンでは修正されていないため、唯一の解決策はより高いバージョンにアップグレードすることです。それにもかかわらず、明確な説明があれば、大いに役立ちます。

関連する問題