signals - Enabling floating point exceptions on MinGW GCC? -


how 1 enable floating point exceptions on mingw gcc, feenableexcept missing? reasonably complete solutions don't catch this, though appear intend to. prefer minimal code close whatever future standards emerge. preferably, code should work , without sse. complete solution shows how enable hardware signal, catch it, , reset preferable. compiling cleanly high optimization levels , full pedantic errors , warnings must. ability catch multiple times in unit-test scenario important. there several questions provide partial answers.

this appears work on machine. compile in mingw gcc -fnon-call-exceptions. isn't minimized yet.

#include <xmmintrin.h> #include <cerrno> #include <cfenv> #include <cfloat> //or #include <float.h> // defines _controlfp_s #include <cmath> #include <csignal>  #ifdef _win32 void feenableexcept(uint16_t fpflags){  /*edit 2015-12-17, attempt @ asm code giving me   *problems in more complicated scenarios,   *switched using _controlfp_s. posted here   *because of upvote asm version.*/  /*{// http://stackoverflow.com/questions/247053/   uint16_t mask(fe_all_except & ~fpflags);   asm("fldcw %0" : : "m" (mask) : "cc");  } //https://gcc.gnu.org/onlinedocs/gcc/extended-asm.html   */  unsigned int new_word(0);  if (fpflags & fe_invalid) new_word |= _em_invalid;  if (fpflags & fe_divbyzero) new_word |= _em_zerodivide;  if (fpflags & fe_overflow) new_word |= _em_overflow;  unsigned int cw(0);  _controlfp_s(&cw,~new_word,_mcw_em); } #endif  void fe_reset_traps(){  std::feclearexcept(fe_all_except); //clear x87 fe state #ifdef __sse__  _mm_set_exception_state(0); // clear sse fe state #endif  feenableexcept(fe_divbyzero|fe_overflow|fe_invalid); // set x87 fe mask #ifdef __sse__  //set sse fe mask (orientation of command different above)  _mm_set_exception_mask(_mm_mask_denorm |_mm_mask_underflow|_mm_mask_inexact); #endif }  void sigfpe_handler(int sig){  std::signal(sig,sig_dfl); // block signal, if needed  std::cerr<<"a floating point exception encountered. exiting.\n";  fe_reset_traps(); // in testing mode throw may not exit, reset traps  std::signal(sig,&sigfpe_handler); // reinstall handler  throw std::exception(); }  fe_reset_traps(); std::signal(sigfpe,&sigfpe_handler); // install handler std::cerr<<"before\n"; std::cerr<<1.0/0.0<<"\n"; std::cerr<<"should unreachable\n"; 

i'm sure it's not perfect. let's hear else has contribute.


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -