In languages like C, integer overflow wraps around for unsigned
integer types that are at least as wide as unsigned int
;
e.g., UINT_MAX + 1
yields zero.
This is guaranteed by the C standard and is
portable in practice, unless you specify aggressive,
nonstandard optimization options
suitable only for special applications.
In contrast, the C standard says that signed integer overflow leads to
undefined behavior where a program can do anything, including dumping
core or overrunning a buffer. The misbehavior can even precede the
overflow. Such an overflow can occur during addition, subtraction,
multiplication, division, and left shift. It can even occur for
unsigned types like unsigned short int
that are narrower
than int
, as values of these types are widened to int
before computation.
Despite this requirement of the standard, some C programs assume that
signed integer overflow silently wraps around modulo a power of two,
using two’s complement arithmetic, so long as you convert the resulting
value to a signed integer type. These programs can have problems,
especially when optimization is enabled. If you assume a GCC-like
compiler, you can work around the problems by compiling with GCC’s
-fwrapv
option; however, this is not portable.
For historical reasons C17 and earlier also allowed implementations with ones’ complement or signed magnitude arithmetic, but C23 requires two’s complement and it is safe to assume two’s complement nowadays.
Also, overflow can occur when converting an out-of-range value to a signed integer type. Here a standard implementation must define what happens, and this can include raising an exception. Although practical implementations typically wrap around silently in this case, a few debugging implementations trap instead.