6

I've been getting a Floating point exception (core dumped) error in my C++ program, and gdb shows that the problem is on a line that performs modulo division:

Program received signal SIGFPE, Arithmetic exception.
[Switching to Thread 0x7ffff6804700 (LWP 13931)]
0x00000000004023e8 in CompExp::eval (this=0x7fffec000e40, currVal=0)
    at exp.cpp:55
55              return (r==0) ? 0 : l % r;

The line guards against dividing by zero, and my backtrace shows the following:

#0  0x00000000004023e8 in CompExp::eval (this=0x7fffec000e40, currVal=0)
    at exp.cpp:55
        l = -2147483648
        r = -1

Since I know I'm not dividing by zero, what else could possibly be causing the exception?

crognale
  • 171
  • 1
  • 1
  • 6
  • 2
    The modulo of a negative number is undefined, it's probably that, you probably should have (r <= 0) – PeterJ Dec 31 '12 at 05:47
  • @PeterJ, Interesting, the operation, in my opinion, makes sense for a negative number, but you're right. – chris Dec 31 '12 at 05:50

3 Answers3

11

So I figured out what was causing the problem -- An arithmetic exception can be triggered either by dividing by zero, or overflow of a signed integer, which is what happened here. Unsigned integers are required to wrap around when overflowed; the behavior for signed integers is undefined.

crognale
  • 171
  • 1
  • 1
  • 6
6

Change the code to the following to avoid trying to take the modulo of a negative number which is undefined:

return (r<=0) ? 0 : l % r;
PeterJ
  • 3,705
  • 28
  • 51
  • 71
  • 1
    This seems to have changed in C++11. Take a look at [this](http://stackoverflow.com/questions/7594508/modulo-operator-with-negative-values). – chris Dec 31 '12 at 05:53
  • 1
    If I make a small program with only `int i = -2147483648 % -1;`, then there is no exception, so I don't think that it would be a problem with taking the modulo of a negative number. – crognale Dec 31 '12 at 05:56
  • @chris, interesting, I suspect it's one of those edge cases that some compilers handle differently. – PeterJ Dec 31 '12 at 05:58
  • @PeterJ, Well, before C++11, it was implementation-defined, so they're free to do what they will. It is interesting that the standard revisited that, though. – chris Dec 31 '12 at 06:00
  • @crognale The compiler is [folding](https://en.wikipedia.org/wiki/Constant_folding) that constant expression, so that `i` gets assigned to the expression result during compilation, not at run-time. – DocKimbel Aug 04 '17 at 13:05
2

In order to calculate such modulo expression: -2147483648 % -1, a division is required, which in this case, seems to be a 32-bit division (I guess l and r are defined as int). The right result of such division would be 2147483648, but that value cannot be represented in 32-bit, so an arithmetic exception is produced.

DocKimbel
  • 3,127
  • 16
  • 27