在MinGW GCC上启用浮点异常?

在MinGW GCC上启用浮点异常?,gcc,signals,mingw-w64,floating-point-exceptions,Gcc,Signals,Mingw W64,Floating Point Exceptions,如何在缺少的位置启用浮点异常?即使他们真的没有抓住这一点,尽管看起来他们是有意的。我更喜欢接近未来标准的最小代码。最好是,代码可以与SSE一起工作,也可以不与SSE一起工作。一个完整的解决方案,显示如何启用硬件信号,捕捉它,并重置它是可取的。必须使用高优化级别和全面的错误和警告进行干净的编译。在单元测试场景中捕获多次的能力很重要。有几个问题。这似乎在我的机器上起作用。在MinGW GCC中编译它,并带有-fnon-call异常。它还没有完全最小化 #include <xmmintrin.h

如何在缺少的位置启用浮点异常?即使他们真的没有抓住这一点,尽管看起来他们是有意的。我更喜欢接近未来标准的最小代码。最好是,代码可以与SSE一起工作,也可以不与SSE一起工作。一个完整的解决方案,显示如何启用硬件信号,捕捉它,并重置它是可取的。必须使用高优化级别和全面的错误和警告进行干净的编译。在单元测试场景中捕获多次的能力很重要。有几个问题。

这似乎在我的机器上起作用。在MinGW GCC中编译它,并带有
-fnon-call异常
。它还没有完全最小化

#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, my attempt at ASM code was giving me
  *problems in more complicated scenarios, so I
  *switched to using _controlfp_s. I finally posted it here
  *because of the upvote to the 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 this command is different than the 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 was encountered. Exiting.\n";
 fe_reset_traps(); // in testing mode the throw may not exit, so 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 be unreachable\n";
#包括
#包括
#包括
#包含//或#包含//定义_控制
#包括
#包括
#ifdef_WIN32
无效feenableexcept(uint16\u t fpflags){
/*编辑2015-12-17,我尝试使用ASM代码时
*更复杂场景中的问题,所以我
*切换到使用_controlfp_s。我终于在这里发布了它
*因为对ASM版本的升级投票*/
/*{// http://stackoverflow.com/questions/247053/
uint16屏蔽(除&~fpflags外的所有FE屏蔽);
asm(“fldcw%0”:“m”(掩码):“cc”);
} //https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html   */
无符号整数新字(0);
如果(fpflags&FE_INVALID)新单词|=_EM_INVALID;
如果(fpflags&FE_DIVBYZERO)新单词|=_EM_zero divide;
如果(fpflags&FE_溢出)新单词|=_EM_溢出;
无符号整数cw(0);
_控制系统(&cw,~new\u word,\u MCW\u EM);
}
#恩迪夫
无效fe_重置_陷阱(){
std::feclearException(FE_ALL_Exception);//清除x87 FE状态
#ifdef__SSE__
_MM_SET_EXCEPTION_STATE(0);//清除SSE FE状态
#恩迪夫
feenableexcept(FE_除以零| FE_溢出| FE_无效);//设置x87 FE掩码
#ifdef__SSE__
//设置SSE FE掩码(此命令的方向与上述方向不同)
_MM_设置_异常_掩码(_MM_掩码| _MM_掩码| | _MM_掩码|不精确);
#恩迪夫
}
无效sigfpe_处理器(int sig){
std::signal(sig,sig_DFL);//如果需要,阻塞信号
标准:cerr