All operations on “standard” signed integer types in C (short, int, long, etc) exhibit undefined behaviour if they yield a result outside of the [TYPE_MIN, TYPE_MAX] interval (where TYPE_MIN, TYPE_MAX are the minimum and the maximum integer value respectively. that can be stored by the specific integer type.
According to the C99 standard, however, all intN_t types are required to have a two’s complement representation:
7.8.11.1 Exact-width integer types
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 a signed integer
type with a width of exactly 8 bits.
Does this mean that intN_t types in C99 exhibit well-defined behaviour in case of an integer overflow? For example, is this code well-defined?
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
return 0;
}
No, it doesn’t.
The requirement for a 2’s-complement representation for values within the range of the type does not imply anything about the behavior on overflow.
The types in
<stdint.h>are simply typedefs (aliases) for existing types. Adding a typedef doesn’t change a type’s behavior.Section 6.5 paragraph 5 of the C standard (both C99 and C11) still applies:
This doesn’t affect unsigned types because unsigned operations do not overflow; they’re defined to yield the wrapped result, reduced modulo TYPE_MAX + 1. Except that unsigned types narrower than
intare promoted to (signed)int, and can therefore run into the same problems. For example, this:causes undefined behavior if
shortis narrower thanint. (Ifshortandintare 16 and 32 bits, respectively, then65535 * 65535yields4294836225, which exceedsINT_MAX.)