what does C/C++ handler SIGFPE?

对着背影说爱祢 提交于 2020-12-30 07:36:32

问题


well, I have searched the articles about SIGFPE ,then I wrote a few tests but it's behavoir is strange. 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?

1) I searched the article : Division by zero does not throw SIGFPE it sames the output is inf

2) If I rewrite it as the following:

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. but if I uncomment the line

//fprintf(stderr,"d number is %d\n,d);

then signal_handler keeps calling.

can someone explains it ?


回答1:


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.

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. 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? If so, there could be issues with underlying system calls restarting. Try: siginterrupt(SIGFPE, 1); (assuming it's available).




回答2:


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. See signal(7) for the restrictions.




回答3:


Why signal_handler will not happens: compiler optimization killed division for unused result.

Why signal_handler keeps calling: After return from signal handler, FPE re-execute same instruction. You can avoid it by using 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




回答4:


Is the GCC/G++ or ISO C++ clearly defined what happens if divide by zero?

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. 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.

if I uncomment the line //fprintf(stderr,"d number is %d\n,d); then signal_handler keeps calling. can someone explains it ?

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). This happens because the language can't foresee what will happen (remember, it's UB) so it might as well assume nothing happens.



来源:https://stackoverflow.com/questions/14905947/what-does-c-c-handler-sigfpe

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!