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:
INT_ADD_WRAPV (a, b, r)
¶Store the low-order bits of the sum of a and b into
*r
. Yield 1 if overflow occurred, 0 if the
low-order bits are the mathematically-correct sum. See above for
restrictions.
INT_SUBTRACT_WRAPV (a, b, r)
¶Store the low-order bits of the difference between a and b
into *r
. Yield 1 if overflow occurred, 0 if the
low-order bits are the mathematically-correct difference. See above
for restrictions.
INT_MULTIPLY_WRAPV (a, b, r)
¶Store the low-order bits of the product of a and b into
*r
. Yield 1 if overflow occurred, 0 if the
low-order bits are the mathematically-correct product. See above for
restrictions.
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).
Next: Integer Type Overflow, Previous: Checking Integer Overflow, Up: Integer Properties [Contents][Index]