Ich habe Schwierigkeiten, eine zuverlässige Möglichkeit zu erhalten, Gleitkommaausnahmen unter Visual Studio (2005 oder 2008) zu fangen. In Visual Studio werden Gleitkommaausnahmen standardmäßig nicht abgefangen, und sie sind ziemlich schwer zu fangen (hauptsächlich, weil die meisten Hardwaresignale sind und in Ausnahmen übersetzt werden müssen).Visual C++/Seltsames Verhalten nach dem Aktivieren von Gleitkommaausnahmen (Compilerfehler?)
Hier ist, was ich getan habe:
- Schalen Sie SEH Behandlung von Ausnahmen
(Eigenschaften/Code-Generierung aktivieren/C++ Ausnahmen: Ja mit SEH Ausnahmen)
- Aktivieren Gleitpunkte Ausnahmen mit _controlfp
ich fange nun die Ausnahmen (wie im Beispiel unten gezeigt was eine einfache Division durch Null Ausnahme). Sobald ich jedoch diese Ausnahme abfangen, scheint es, dass das Programm irreversibel beschädigt ist (da einfache Float-Initialisierung sowie std :: cout nicht funktionieren!).
Ich habe ein einfaches Demo-Programm gebaut, das dieses seltsame Verhalten zeigt.
Hinweis: Dieses Verhalten wurde auf mehreren Computern reproduziert.
#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();
}
Hat jemand eine Ahnung, was getan werden könnte, um diese Situation zu korrigieren? Vielen Dank im Voraus!
Eine wichtige Anmerkung jedoch: _fpreset() löscht das Fließkomma-Statuswort * und * reinitialisiert das Fließkomma-Mathe-Paket, d. H. Es werden keine Ausnahmen nachträglich ausgelöst. Um nachfolgende Ausnahmen nicht zu deaktivieren, kann stattdessen _clearfp() verwendet werden –
Ich hatte das gleiche Problem wie der OQ (also ein großer +1 für euch beide). –