[英]what does C/C++ handler SIGFPE?
well, I have searched the articles about SIGFPE ,then I wrote a few tests but it's behavoir is strange. 好吧,我搜索了有关SIGFPE的文章,然后我写了一些测试,但它的行为很奇怪。 Then I have to post it here to ask for help. 然后我必须在这里发帖寻求帮助。 Is the GCC/G++ or ISO C++ clearly defined what happens if divide by zero? GCC / G ++或ISO C ++是否明确定义了如果除以零会发生什么?
1) I searched the article : Division by zero does not throw SIGFPE it sames the output is inf 1)我搜索了这篇文章: 除零之后不会抛出SIGFPE同样输出是inf
2) If I rewrite it as the following: 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;
}
then signal_handler will not happens. 然后signal_handler将不会发生。 but if I uncomment the line 但如果我取消注释该行
//fprintf(stderr,"d number is %d\n,d);
then signal_handler keeps calling. 然后signal_handler继续打电话。
can someone explains it ? 有人可以解释一下吗?
This is interesting: With the fprintf
commented out, the compiler has determined that the calculated result: d = b/c
is an unused local expression and can be optimized away. 这很有趣:在fprintf
注释掉后,编译器确定计算结果: d = b/c
是一个未使用的本地表达式,可以进行优化。
Clearly though, it is not side-effect free in its execution, but the compiler can't determine anything about the runtime environment at this stage. 显然,它在执行时没有副作用,但编译器无法在此阶段确定有关运行时环境的任何信息。 I'm surprised that static analysis doesn't pick this up as a warning (at least) in a modern compiler. 我很惊讶静态分析不会在现代编译器中将其作为警告(至少)。
@vonbrand is right. @vonbrand是对的。 You got lucky with what you're doing in the (asynchronous) signal handler. 你在(异步)信号处理程序中所做的事情很幸运。
Edit: when you say "signal_handler keeps calling", do you mean it's repeating indefinitely? 编辑:当你说“signal_handler一直在呼唤”时,你的意思是它无限期地重复吗? If so, there could be issues with underlying system calls restarting. 如果是这样,可能会出现重启基础系统调用的问题。 Try: siginterrupt(SIGFPE, 1);
尝试: siginterrupt(SIGFPE, 1);
(assuming it's available). (假设它可用)。
There are only a few operations allowed in signal handlers, and using any buffered I/O ( std::cout
et al, but also fprintf(3)
, which BTW I don't know if it mixes well with the previous one) is out of the question. 在信号处理程序中只允许一些操作,并且使用任何缓冲的I / O( std::cout
等人,还有fprintf(3)
,BTW我不知道它是否与之前的混合很好)不可能的。 See signal(7)
for the restrictions. 有关限制,请参阅signal(7)
。
Why signal_handler will not happens: compiler optimization killed division for unused result. 为什么signal_handler不会发生:编译器优化会因未使用的结果而导致分裂。
Why signal_handler keeps calling: After return from signal handler, FPE re-execute same instruction. 为什么signal_handler一直在调用:从信号处理程序返回后,FPE重新执行相同的指令。 You can avoid it by using longjmp. 您可以使用longjmp来避免它。
Here is my well-working code for the purpose (at least on Mac OS X) https://github.com/nishio/learn_language/blob/master/zero_division/zero_division.cpp 这是我用于此目的的良好代码(至少在Mac OS X上) https://github.com/nishio/learn_language/blob/master/zero_division/zero_division.cpp
Is the GCC/G++ or ISO C++ clearly defined what happens if divide by zero? GCC / G ++或ISO C ++是否明确定义了如果除以零会发生什么?
As far as the standard goes, division by zero is Undefined Behaviour, anything could happen. 就标准而言,除以零是未定义行为,任何事情都可能发生。
In practice, even though the standard says it is UB, it is actually implementation-defined at the OS (not language/compiler) level. 实际上,即使标准说它是UB,它实际上是在OS(而不是语言/编译器)级别实现定义的。 On POSIX this will indeed generate a SIGFPE, on Windows it will throw an exception (Windows' SEH exception, not a C++ exception even though some compilers additionally map SEH to C++ exceptions), etc. 在POSIX上,这确实会生成一个SIGFPE,在Windows上会抛出异常(Windows的SEH异常,而不是C ++异常,即使某些编译器还将SEH映射到C ++异常)等。
if I uncomment the line
//fprintf(stderr,"d number is %d\\n,d);
then signal_handler keeps calling. can someone explains it ? 如果我取消注释//fprintf(stderr,"d number is %d\\n,d);
然后signal_handler继续调用。有人可以解释吗?
As others have said, this is because the compiler detects that d
is never used and optimizes away the calculation (as well as the b
and c
definitions in all probability). 正如其他人所说的那样,这是因为编译器检测到d
从未使用过并且优化了计算(以及所有概率中的b
和c
定义)。 This happens because the language can't foresee what will happen (remember, it's UB) so it might as well assume nothing happens. 发生这种情况是因为语言无法预见会发生什么(记住,它是UB)所以它也可能假设没有任何反应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.