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

#### 15.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 returning 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 returns true, whereas ```INT_ADD_OK (INT_MAX, 1, &i)``` returns false.

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 return true. Otherwise return false, 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 return true. Otherwise return false, 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 return true. Otherwise return false, 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), or if you need to check for overflow in operations other than addition, subtraction, and multiplication (see Integer Type Overflow).

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