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


17.7.6 Integer Range Overflow

These macros yield 1 if the corresponding C operators might not yield numerically correct answers due to arithmetic overflow, and 0 if if the operators do not overflow. They do not rely on undefined or implementation-defined behavior. They are integer constant expressions if their arguments are. Their implementations are simple and straightforward, but they are typically harder to use than the integer type overflow macros. See Integer Type Overflow.

Although the implementation of these macros is similar to that suggested in the SEI CERT C Secure Coding Standard, in its two sections “INT30-C. Ensure that unsigned integer operations do not wrap” and “INT32-C. Ensure that operations on signed integers do not result in overflow”, Gnulib’s implementation was derived independently of CERT’s suggestions.

Example usage:

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

void
print_product (long int a, long int b)
{
  if (INT_MULTIPLY_RANGE_OVERFLOW (a, b, LONG_MIN, LONG_MAX))
    printf ("multiply would overflow");
  else
    printf ("product is %ld", a * b);
}

/* Does the product of two ints always fit
   in a long int?  */
enum {
  INT_PRODUCTS_FIT_IN_LONG
    = ! (INT_MULTIPLY_RANGE_OVERFLOW
         ((long int) INT_MIN, (long int) INT_MIN,
          LONG_MIN, LONG_MAX))
};

These macros have the following restrictions:

These macros are tuned for constant min and max. For commutative operations such as a + b, they are also tuned for constant b.

INT_ADD_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a + b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions.

INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a - b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions.

INT_NEGATE_RANGE_OVERFLOW (a, min, max)

Yield 1 if -a would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions.

INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a * b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions.

INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a / b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions. Division overflow can happen on two’s complement hosts when dividing the most negative integer by -1. This macro does not check for division by zero.

INT_REMAINDER_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a % b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions. Remainder overflow can happen on two’s complement hosts when dividing the most negative integer by -1; although the mathematical result is always 0, in practice some implementations trap, so this counts as an overflow. This macro does not check for division by zero.

INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, min, max)

Yield 1 if a << b would overflow in [min,max] integer arithmetic, 0 otherwise. See above for restrictions. Here, min and max are for a only, and b need not be of the same type as the other arguments. The C standard says that behavior is undefined for shifts unless 0≤b<w where w is a’s word width, and that when a is negative then a << b has undefined behavior, but this macro does not check these other restrictions.


Previous: Integer Type Overflow, Up: Integer Properties   [Contents][Index]