Next: Integer Type Overflow, Previous: Checking Integer Overflow, 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, on a typical machine with 32-bit two’s
complement `int`

the expression `INT_MAX + 1`

does not
necessarily yield `INT_MIN`

, because the compiler may do
calculations with a 64-bit register, or may generate code that
traps on signed integer overflow.

The following macros work around this problem by storing the
wraparound value, i.e., the low-order bits of the correct answer, and
by yielding an overflow indication. For example, if `i`

is of
type `int`

, `INT_ADD_WRAPV (INT_MAX, 1, &i)`

sets `i`

to `INT_MIN`

and yields 1 on a two’s complement machine.
See Integer Type Overflow.

Example usage:

#include <intprops.h> #include <stdio.h> /* Print the low order bits of A * B, reporting whether overflow occurred. */ void print_product (long int a, long int b) { long int r; int overflow = INT_MULTIPLY_WRAPV (a, b, &r); printf ("result is %ld (%s)\n", r, (overflow ? "after overflow" : "no overflow")); }

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_WRAPV (`

¶`a`,`b`,`r`)Store the low-order bits of the sum of

`a`and`b`into`*`

. Yield 1 if overflow occurred, 0 if the low-order bits are the mathematically-correct sum. See above for restrictions.`r``INT_SUBTRACT_WRAPV (`

¶`a`,`b`,`r`)Store the low-order bits of the difference between

`a`and`b`into`*`

. Yield 1 if overflow occurred, 0 if the low-order bits are the mathematically-correct difference. See above for restrictions.`r``INT_MULTIPLY_WRAPV (`

¶`a`,`b`,`r`)Store the low-order bits of the product of

`a`and`b`into`*`

. Yield 1 if overflow occurred, 0 if the low-order bits are the mathematically-correct product. See above for restrictions.`r`

If your code includes `<intprops.h>`

only for these `_WRAPV`

macros, you may prefer to use Gnulib’s `stdckdint`

module
instead, as it supports similar macros that were standardized in C23
and are therefore independent of Gnulib if your code can assume C23 or
later. See `stdckdint.h`.

Other macros are available if you do not need wrapped-around results when overflow occurs (see Checking Integer Overflow), or if you need to check for overflow in operations other than addition, subtraction, and multiplication (see Integer Type Overflow).