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

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:

- Their first two arguments must be integer expressions.
- Their last argument must be a non-null pointer to an integer.
- They may evaluate their arguments zero or multiple times, so the arguments should not have side effects.
- They are not necessarily constant expressions, even if all their arguments are constant expressions.

`INT_ADD_OK (`

¶`a`,`b`,`r`)Compute the sum of

`a`and`b`. If it fits into`*`

, store it there and yield 1. Otherwise yield 0, possibly modifying`r``*`

to an unspecified value. See above for restrictions.`r``INT_SUBTRACT_OK (`

¶`a`,`b`,`r`)Compute the difference between

`a`and`b`. If it fits into`*`

, store it there and yield 1. Otherwise yield 0, possibly modifying`r``*`

to an unspecified value. See above for restrictions.`r``INT_MULTIPLY_OK (`

¶`a`,`b`,`r`)Compute the product of

`a`and`b`. If it fits into`*`

, store it there and yield 1. Otherwise yield 0, possibly modifying`r``*`

to an unspecified value. See above for restrictions.`r`

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).