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


14.5.4 Integer Type Overflow

Although unsigned integer arithmetic wraps around modulo a power of two, signed integer arithmetic has undefined behavior on overflow in C. Almost all modern computers use two’s complement signed arithmetic that is well-defined to wrap around, but C compilers routinely optimize based on the assumption that signed integer overflow cannot occur, which means that a C program cannot easily get at the underlying machine behavior. For example, the signed integer expression (a + b < b) != (a < 0) is not a reliable test for whether a + b overflows, because a compiler can assume that signed overflow cannot occur and treat the entire expression as if it were false.

These macros yield 1 if the corresponding C operators might not yield numerically correct answers due to arithmetic overflow of an integer type. They work correctly on all known practical hosts, and do not rely on undefined behavior due to signed arithmetic overflow. They are integer constant expressions if their arguments are. They are typically easier to use than the integer range overflow macros (see Integer Range Overflow), and they support more operations and evaluation contexts than the wraparound macros (see Wraparound Arithmetic).

Example usage:

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

/* Print A * B if in range, an overflow
   indicator otherwise.  */
void
print_product (long int a, long int b)
{
  if (INT_MULTIPLY_OVERFLOW (a, b))
    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_OVERFLOW
         ((long int) INT_MIN, INT_MIN))
};

These macros have the following restrictions:

These macros are tuned for their last argument being a constant.

INT_ADD_OVERFLOW (a, b)

Yield 1 if a + b would overflow. See above for restrictions.

INT_SUBTRACT_OVERFLOW (a, b)

Yield 1 if a - b would overflow. See above for restrictions.

INT_NEGATE_OVERFLOW (a)

Yields 1 if -a would overflow. See above for restrictions.

INT_MULTIPLY_OVERFLOW (a, b)

Yield 1 if a * b would overflow. See above for restrictions.

INT_DIVIDE_OVERFLOW (a, b)

Yields 1 if a / b would overflow. 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_OVERFLOW (a, b)

Yield 1 if a % b would overflow. 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_OVERFLOW (a, b)

Yield 1 if a << b would overflow. See above for restrictions. 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.


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