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:

• 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 `*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]