In C99 there're some (optional) types like int8_t
, int16_t
and the like, which are guaranteed to be have exactly specified width and no padding bits, and represent numbers in two's complement (7.18.1.1). In 6.2.6.2 signed integer overflow is mentioned as footnotes 44) and 45), namely that it might result in trapping values in padding bits.
As intN_t
don't have any padding bits, and they are guaranteed to be two's complement, does this mean that their overflow doesn't generate any undefined behavior? What would be the result of e.g. overflowing multiplication? What about addition? Is the result reduced modulo 2^N
as for unsigned types?
Footnotes are not normative. If a footnote states that overflow can result in trapping values in padding bits, it is not really wrong, but I can see how it is slightly misleading. The normative text merely says the behaviour is undefined. Placing trapping values in padding bits is one possible consequence of undefined behaviour, but not the only one.
So no, this does not mean overflow is defined. It's possible for operations involving
intN_t
/uintN_t
operands to overflow, and for that overflow to result in undefined behaviour.Something like
int8_t i = 127; ++i;
has no UB.int8_t
is subject to integral promotions, so the addition is carried out as if you had writteni = (int8_t) ((int) i + 1);
. The addition itself does not overflow, and the conversion back toint8_t
produces an implementation-defined result.Something like
uint16_t u = 65535; u *= u;
has UB on current typical implementations whereint
has 32 sign/value bits.uint16_t
too is subject to integral promotions, so the multiplication is carried out as if you had writtenu = (uint16_t) ((int) u * (int) u);
. The multiplication itself overflows, and the behaviour is undefined.Something like
int64_t i = 9223372036854775807; ++i;
has UB on almost all implementations. The addition itself overflows.