Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trapping floating-point overflow in C

I am trying to trap floating-point overflow in C. Here is what I have tried

#define _GNU_SOURCE

#include <fenv.h>
#include <signal.h>
#include <stdio.h>

void catch_overflow (int sig) {   
  printf ("caught division by zero\n");   
  signal (sig, catch_overflow); 
}


int main(void) {   
  feenableexcept(FE_DIVBYZERO);   
  signal (FE_DIVBYZERO, catch_overflow);


  float a = 1., b = 0.;   float c = a/b;   return 0; }

I expected to see "caught division by zero" message, but I only get a core dump message, "Floating point exception (core dumped)". How could I modify the program to get the "caught division by zero" message?

Thanks.

like image 856
wad Avatar asked Jul 24 '17 19:07

wad


People also ask

How do you handle floating point exception?

By default, the system has all FP exceptions turned off. Therefore, computations result in NAN or INFINITY, rather than an exception. Before you can trap floating-point (FP) exceptions using structured exception handling, you must call the _controlfp_s C run-time library function to turn on all possible FP exceptions.

What is floating point exception in c programming?

Floating-point exception when there is an error in floating-point arithmetic. Causes of floating-point exception include invalid operation and overflow. You cannot avoid floating-point errors, but you can manage them. SIGFPE is a signal raised by the floating-point exception.

How do you raise a Sigfpe?

The SIGFPE signal is raised when a computational error occurs. These errors include floating-point overflow, floating-point underflow, and either integer- or floating-point division by 0.


1 Answers

A floating point exception is translated in machine- and OS-dependent way to some signaling approach. But no such way allows mixing of different constant spaces, as FE_xxx and SIGxxx. Using FE_DIVBYZERO for signal(), you really caught SIGILL which is not generated for floating-point errors (because you did not specify OS, I was free to choose any - Linux in my case).

For your program, I have made this exception catching working under Linux with two changes:

  1. Setting signal number to handle to SIGFPE.

  2. Declaring a, b, c as volatile (prevents compiler from calculating c as INF at compile time).

After this, the program fell into eternal cycle printing "caught division by zero" because signal handler for such error restores execution to the same command. You shall carefully consider how to fix such errors without making an erroneous instruction eternal. For example, you can use longjmp to go out of signal handler to an installed exception handler.

And, you still should consult your target OS manuals for how to catch FP errors.

(This has been already described in comments in main parts - but I considered to form an explicit answer.)

like image 139
Netch Avatar answered Oct 23 '22 11:10

Netch