嗯,我已经搜索了关于SIGFPE的文章,然后我写了一些测试,但它的行为是奇怪的。那我就得把它寄到这里寻求帮助。GCC/G++或C++是明确定义的吗?如果除以零会发生什么?
1)我搜索了一篇文章:Division by zero does not throw SIGFPE,它的输出是inf
2)如果我将其改写如下:
void signal_handler (int signo) {
if(signo == SIGFPE) {
std::cout << "Caught FPE\n";
}
}
int main (void) {
signal(SIGFPE,(*signal_handler));
int b = 1;
int c = 0;
int d = b/c;
//fprintf(stderr,"d number is %d\n,d);
return 0;
}那么signal_handler就不会发生了。但如果我取消评论的话
//fprintf(stderr,"d number is %d\n,d);然后signal_handler继续打电话。
有人能解释一下吗?
发布于 2013-02-16 01:38:42
这很有趣:在fprintf注释掉之后,编译器已经确定了计算结果:d = b/c是一个未使用的本地表达式,可以进行优化。
显然,在它的执行过程中,它并不是没有副作用的,但是编译器在这个阶段无法确定任何关于运行时环境的信息。我感到惊讶的是,静态分析并没有将其作为一个警告(至少在现代编译器中)。
@vonbrand是对的。您在(异步)信号处理程序中所做的事情很幸运。
编辑:,当你说"signal_handler不停地打电话“时,你的意思是无限期地重复吗?如果是这样的话,底层系统调用可能会出现重新启动的问题。尝试:siginterrupt(SIGFPE, 1); (假设它是可用的)。
发布于 2013-02-16 01:35:41
信号处理程序中只允许几个操作,使用任何缓冲I/O (std::cout等人,但也可以使用fprintf(3),我不知道它是否与前面的操作混合得很好)是不可能的。有关限制,请参见signal(7)。
发布于 2014-05-19 02:41:43
为什么不会发生signal_handler :编译器优化会扼杀未使用结果的除法。
为什么signal_handler继续调用:从信号处理程序返回后,FPE重新执行相同的指令.您可以通过使用longjmp来避免这种情况。
下面是我的工作良好的代码(至少在Mac OS X上) division.cpp
https://stackoverflow.com/questions/14905947
复制相似问题