Visual Studio(2005または2008)で浮動小数点例外を確実に捕捉するのに苦労しています。デフォルトでは、ビジュアルスタジオの下では、浮動小数点例外は捕捉されず、(ハードウェア信号のほとんどが例外であり、例外に変換される必要があるため)捕捉するのが非常に難しいです。浮動小数点例外を有効にした後のVisual C++ /奇妙な振る舞い(コンパイラのバグ?)
ここで私は何をしましたか:
は -
取り扱い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();
}
誰でもこの状況を修正するための手がかりを持っていますか? 事前に感謝します!
ただし、_fpreset()は浮動小数点ステータスワード*をクリアし、浮動小数点数学パッケージを再初期化します。つまり、後で例外はスローされません。その後の例外を無効にしないために、代わりに_clearfp()を使用することができます –
私はOQと同じ問題を抱えていました。 –