Next: , Previous: , Up: Integer Properties   [Contents][Index]


17.7.3 Checking Integer Overflow

Signed integer arithmetic has undefined behavior on overflow in C. Although almost all modern computers use two’s complement signed arithmetic that is well-defined to wrap around, C compilers routinely optimize assuming that signed integer overflow cannot occur, which means that a C program cannot easily get at the underlying machine arithmetic. For example:

if ((a + b < b) == (a < 0))
  a += b;
else
  printf ("overflow\n");

might not work as expected if a and b are signed, because a compiler can assume that signed overflow cannot occur and treat the entire if expression as if it were true. And even if a is unsigned, the expression might not work as expected if b is negative or is wider than a.

The following macros work around this problem by yielding an overflow indication while computing the sum, difference, or product of two integers. For example, if i is of type int, INT_ADD_OK (INT_MAX - 1, 1, &i) sets i to INT_MAX and yields 1, whereas INT_ADD_OK (INT_MAX, 1, &i) yields 0.

Example usage:

#include <intprops.h>
#include <stdio.h>

/* Compute A * B, reporting whether overflow occurred.  */
void
print_product (long int a, long int b)
{
  long int r;
  if (INT_MULTIPLY_OK (a, b, &r))
    printf ("result is %ld\n", r);
  else
    printf ("overflow\n");
}

These macros work for both signed and unsigned integers, so they can be used with integer types like time_t that may or may not be signed, depending on the platform.

These macros have the following restrictions:

INT_ADD_OK (a, b, r)

Compute the sum of a and b. If it fits into *r, store it there and yield 1. Otherwise yield 0, possibly modifying *r to an unspecified value. See above for restrictions.

INT_SUBTRACT_OK (a, b, r)

Compute the difference between a and b. If it fits into *r, store it there and yield 1. Otherwise yield 0, possibly modifying *r to an unspecified value. See above for restrictions.

INT_MULTIPLY_OK (a, b, r)

Compute the product of a and b. If it fits into *r, store it there and yield 1. Otherwise yield 0, possibly modifying *r to an unspecified value. See above for restrictions.

Other macros are available if you need wrapped-around results when overflow occurs (see Wraparound Arithmetic with Integers), or if you need to check for overflow in operations other than addition, subtraction, and multiplication (see Integer Type Overflow).


Next: Wraparound Arithmetic with Integers, Previous: Integer Bounds, Up: Integer Properties   [Contents][Index]