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

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 overflow, 0 otherwise. 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 integer overflow checking macros (see Checking Integer Overflow) or the wraparound macros (see Wraparound Arithmetic with Integers).

These macros can be tricky to use with arguments narrower than
`int`

. For example, in the common case with 16-bit ```
short
int
```

and 32-bit `int`

, if `a`

and `b`

are of type
`short int`

then `INT_MULTIPLY_OVERFLOW (a, b)`

always
yields 0, as `a * b`

cannot overflow due to C’s rule that
`a`

and `b`

are widened to `int`

before multiplying.
For this reason, often it is better to use the integer overflow
checking macros (see Checking Integer Overflow) or the wraparound
macros (see Wraparound Arithmetic with Integers) when checking for overflow in
addition, subtraction, or multiplication.

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:

- Their arguments must be integer expressions.
- They may evaluate their arguments zero or multiple times, so the arguments should not have side effects.

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

`INT_ADD_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 0 otherwise. See above for restrictions.`a`+`b``INT_SUBTRACT_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 0 otherwise. See above for restrictions.`a`-`b``INT_NEGATE_OVERFLOW (`

¶`a`)Yields 1 if

`-`

would overflow, 0 otherwise. See above for restrictions.`a``INT_MULTIPLY_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 0 otherwise. See above for restrictions.`a`*`b``INT_DIVIDE_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 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.`a`/`b``INT_REMAINDER_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 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.`a`%`b``INT_LEFT_SHIFT_OVERFLOW (`

¶`a`,`b`)Yield 1 if

would overflow, 0 otherwise. See above for restrictions. The C standard says that behavior is undefined for shifts unless 0≤`a`<<`b``b`<`w`where`w`is`a`’s word width, and that when`a`is negative then

has undefined behavior, but this macro does not check these other restrictions.`a`<<`b`