# Is signed integer overflow still undefined behavior in C++?

C++C++11Undefined BehaviorInteger Overflow## C++ Problem Overview

As we know, signed integer overflow is undefined behavior. But there is something interesting in C++11 `cstdint`

documentation:

> signed integer type with width of exactly 8, 16, 32 and 64 bits respectively with no padding bits and **using 2's complement for negative values** (provided only if the implementation directly supports the type)

_{See link}

And here is my question: since the standard says explicitly that for `int8_t`

, `int16_t`

, `int32_t`

and `int64_t`

negative numbers are 2's complement, is still overflow of these types an undefined behavior?

**Edit** I checked C++11 and C11 Standards and here is what I found:

C++11, §18.4.1: > The header defines all functions, types, and macros the same as 7.20 in the C standard.

C11, §7.20.1.1:
> The typedef name `intN_t`

designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, `int8_t`

denotes such a signed integer type with a width of exactly 8 bits.

## C++ Solutions

## Solution 1 - C++

> is still overflow of these types an undefined behavior?

**Yes.** Per Paragraph 5/4 of the C++11 Standard (regarding any expression in general):

> If during the evaluation of an expression, the result is not mathematically defined or not in the range of
representable values for its type, **the behavior is undefined**. [...]

The fact that a two's complement representation is used for those signed types does not mean that arithmetic modulo 2^n is used when evaluating expressions of those types.

Concerning *unsigned* arithmetic, on the other hand, the Standard explicitly specifies that (Paragraph 3.9.1/4):

> Unsigned integers, declared `unsigned`

, **shall obey the laws of arithmetic modulo 2^n** where n is the number
of bits in the value representation of that particular size of integer

This means that the result of an unsigned arithmetic operation is always "*mathematically defined*", and the result is always within the representable range; therefore, 5/4 does not apply. Footnote 46 explains this:

> 46) This implies that **unsigned** arithmetic does not overflow because a result that cannot be represented by the resulting
unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the
resulting unsigned integer type.

## Solution 2 - C++

Just because a type is defined to use 2s complement representation, it doesn't follow that arithmetic overflow in that type becomes defined.

The undefined behaviour of signed arithmetic overflow is used to enable optimisations; for example, the compiler can assume that if `a > b`

then `a + 1 > b`

also; this doesn't hold in unsigned arithmetic where the second check would need to be carried out because of the possibility that `a + 1`

might wrap around to `0`

. Also, some platforms can generate a trap signal on arithmetic overflow (see e.g. http://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html); the standard continues to allow this to occur.

## Solution 3 - C++

I would bet so.

From the standard documentation (pg.4 and 5):

> **1.3.24 undefined behavior**
>
> behavior for which this International Standard imposes no requirements
>
> [ Note: Undefined behavior may be expected when this International
> Standard omits any explicit definition of behavior or when a program
> uses an erroneous construct or erroneous data. Permissible undefined
> behavior ranges from ignoring the situation completely with
> unpredictable results, to behaving during translation or program
> execution in a documented manner characteristic of the environment
> (with or without the issuance of a diagnostic message), to terminating
> a translation or execution (with the issuance of a diagnostic
> message). Many erroneous program constructs do not engender undefined
> behavior; they are required to be diagnosed.-- end note]