什么是C/C++处理程序SIGFPE
what does C/C++ handler SIGFPE?
好吧,我已经搜索了关于SIGFPE的文章,然后我写了一些测试,但它的行为很奇怪。然后我不得不把它贴在这里寻求帮助。GCC/G++或ISO C++是否明确定义了如果除以零会发生什么?
1) 我搜索了这篇文章:除以零不会引发SIGFPE它的输出是inf
2) 如果我重写如下:
void signal_handler (int signo) {
if(signo == SIGFPE) {
std::cout << "Caught FPEn";
}
}
int main (void) {
signal(SIGFPE,(*signal_handler));
int b = 1;
int c = 0;
int d = b/c;
//fprintf(stderr,"d number is %dn,d);
return 0;
}
则不会发生signal_handler。但是如果我取消注释行
//fprintf(stderr,"d number is %dn,d);
然后signal_handler继续调用。
有人能解释一下吗?
这很有趣:当fprintf
被注释掉时,编译器已经确定计算结果:d = b/c
是一个未使用的局部表达式,可以进行优化。
很明显,它在执行过程中并不是没有副作用的,但编译器在这个阶段无法确定任何关于运行时环境的信息。我很惊讶静态分析在现代编译器中(至少)没有把这当成一个警告。
@冯布兰德是对的。您很幸运在(异步)信号处理程序中所做的工作。
编辑:当你说"signal_handler一直在呼叫"时,你的意思是它无限期地重复吗?如果是这样,那么重新启动底层系统调用可能会出现问题。尝试:siginterrupt(SIGFPE, 1);
(假设它可用)。
信号处理程序中只允许少数操作,使用任何缓冲I/O(std::cout
等,还有fprintf(3)
,BTW我不知道它是否与前一个混合良好)都是不可能的。有关限制,请参见signal(7)
。
为什么signal_handler不会发生:编译器优化为未使用的结果杀死了除法。
为什么signal_handler不断调用:从信号处理程序返回后,FPE重新执行相同的指令。您可以通过使用longjmp来避免它。
以下是我为此目的编写的运行良好的代码(至少在Mac OS X上)https://github.com/nishio/learn_language/blob/master/zero_division/zero_division.cpp
GCC/G++或ISO C++是否明确定义了如果除以零会发生什么?
就标准而言,除以零就是未定义的行为,任何事情都可能发生。
在实践中,尽管标准说它是UB,但它实际上是在操作系统(而不是语言/编译器)级别定义的实现。在POSIX上,这确实会生成一个SIGFPE,在Windows上,它会抛出一个异常(Windows的SEH异常,而不是C++异常,尽管一些编译器还将SEH映射到C++异常),等等。
如果我取消对
//fprintf(stderr,"d number is %dn,d);
行的注释,那么signal_handler将继续调用。有人能解释一下吗?
正如其他人所说,这是因为编译器检测到从未使用过d
,并优化了计算(以及b
和c
的定义)。发生这种情况是因为语言无法预见会发生什么(记住,它是UB),所以它还不如假设什么都没有发生。
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 为什么我的 IExtractIcon 处理程序没有被调用?
- 在遍历处理程序的向量时注册和注销处理程序
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 通过安装信号处理程序关闭多线程应用程序
- QDateTime::toString() 在退出处理程序中使用时失败
- 如何在 WindowProc 处理程序中区分箭头键和数字键盘?
- async_write完成处理程序最早何时完成?
- C++事件系统 - 多态事件和事件处理程序
- 具有shared_ptr的处理程序中的分段错误
- 为什么我的信号处理程序只执行一次?
- GTK C++:找不到信号处理程序 您是否使用 -rdynamic 进行了编译?
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- C++ 在信号处理程序后继续执行
- wxWidgets 拖放文件事件处理程序初始化问题(无效static_cast)
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 没有信号处理程序的POSIX定时器的目的是什么?
- 处理程序的模块列表中有一个错误的模块"WebSocketModule"