HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMajor

Simple method to detect int overflow

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplemethodoverflowintdetect

Problem

To detect int overflow/underflow in C, I use this code. What might be a simpler and more portable way of coding this (that is, fewer conditions)?

Assume 2's complement and don't use wider integers.

int a,b,sum;
sum = a + b;
// out-of-range only possible when the signs are the same.
if ((a  b) UnderflowDetected();
  }
  else {
    if (sum < b) OverflowDetected();  
  }

Solution

It's not possible to avoid undefined behaviour by testing for it after the fact! If the addition overflows then there is already undefined behaviour here:

sum = a + b;


so attempting to test afterwards is too late. You have to test for possible overflow before you do a signed addition. (If you're puzzled by this, read Dietz et al. (2012), "Understanding Integer Overflow in C/C++". Or even you're not puzzled: it's an excellent paper!)

If it were me, I'd do something like this:

#include 

int safe_add(int a, int b) {
    if (a > 0 && b > INT_MAX - a) {
        /* handle overflow here */
    } else if (a < 0 && b < INT_MIN - a) {
        /* handle underflow here */
    }
    return a + b;
}


but I'm not entirely sure what the point of having separate cases for overflow and underflow is.

I also use Clang's -fsanitize=undefined when building for test.

Update (2023) Several modern compilers now have built-in functions for arithmetic with overflow checking. For example, using GCC's __builtin_add_overflow, we could implement safe_add like this:

int safe_add(int a, int b) {
    int sum;
    if (__builtin_add_overflow(a, b, &sum)) {
        /* handle overflow or underflow here */
    } else {
        return sum;
    }
}

Code Snippets

sum = a + b;
#include <limits.h>

int safe_add(int a, int b) {
    if (a > 0 && b > INT_MAX - a) {
        /* handle overflow here */
    } else if (a < 0 && b < INT_MIN - a) {
        /* handle underflow here */
    }
    return a + b;
}
int safe_add(int a, int b) {
    int sum;
    if (__builtin_add_overflow(a, b, &sum)) {
        /* handle overflow or underflow here */
    } else {
        return sum;
    }
}

Context

StackExchange Code Review Q#37177, answer score: 49

Revisions (0)

No revisions yet.