estoy luchando para conseguir una manera fiable para atrapar flotante señala excepciones bajo Visual Studio (2005 o 2008). De forma predeterminada, en visual studio, las excepciones de punto flotante no son capturadas, y son bastante difíciles de detectar (principalmente porque la mayoría de ellas son señales de hardware y deben traducirse en excepciones)Visual C++/comportamiento extraño después de habilitar las excepciones de punto flotante (error del compilador?)
Esto es lo que hice:
- Activar el manejo
excepciones SEH (/ Habilitar excepciones de generación de propiedades/código C++: Sí, con excepciones SEH)
- Activar flotante señala excepciones usando _controlfp
hago ahora detectar las excepciones (como se muestra en el ejemplo siguiente que una simple división por cero excepción). Sin embargo, tan pronto como veo esta excepción, parece que el programa está irremediablemente dañado (¡ya que la inicialización simple del flotador, así como std :: cout no funcionarán!).
he construido un programa de demostración simple que muestra este comportamiento más bien raro.
Nota: este comportamiento se reprodujo en varios ordenadores.
#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();
}
¿Alguien tiene alguna pista sobre qué se puede hacer para corregir esta situación? ¡Muchas gracias de antemano!
Una nota importante, sin embargo: _fpreset() borrará la palabra de estado de coma flotante * y * reinicializa el paquete de matemáticas de punto flotante, es decir excepciones no serán lanzados posteriormente. Para no deshabilitar excepciones posteriores, _clearfp() se puede usar en su lugar –
Tuve el mismo problema que el OQ (por lo que un gran +1 para ambos). –