On 2024-05-19 14:37, Bruno Haible wrote:
uintN_t arithmetic is overflow-free, just like 'unsigned int' arithmetic.

Not exactly. For example, this:

  uint16_t a = 46341, b = a * a;

has undefined behavior on typical platforms with 32-bit int, because 46341*46341 exceeds 2**31 - 1. Although many programmers would consider this an example of uint16_t arithmetic, something else is going on.

If uintN_t fits in int, a program cannot do uintN_t arithmetic directly, as values are promoted to int before they become arithmetic operands. A program can do only int arithmetic on these values, and the int arithmetic can overflow.

This can happen in C23 even if you're just adding 1, instead of multiplying. For example:

  unsigned _BitInt(31) n = 0x7fffffff, o = 1, p = n + o;

has undefined behavior on typical platforms with 32-bit int, even though n and o are both unsigned.

A similar problem with adding 1 can also occur in C17 and earlier; at least one legacy platform (the Unisys Libra) has INT_MAX == UINT_MAX, so UINT_MAX + 1u has undefined behavior.

Similarly, fully portable code can't rely on standard-defined unsigned types like size_t overflowing nicely, as the overflow might trap if size_t fits in int. Admittedly any platform that traps on size_t overflow would be unpopular - but the standards allow it and arguably some buggy apps would benefit by trapping right away rather than crashing later.

Unsigned int, unsigned long int, unsigned long long int, and uintmax_t are the only types where fully portable code can assume wraparound overflow.


instead
of using the 'u64' module in order to avoid uint64_t, it would be much
simpler to make <stdint.h> define the missing int64_t and uint64_t types

We could do something along those lines. I'd prefer it, though, if we did that only on platforms where we tested that 'unsigned long long int' is actually 64 bits, since the relevant code is already cautious in this area due to concerns such as the above. Although platforms are currently leery of integers wider than 64 bits, wider integers are commonly supported under the covers now, and I expect it won't be forever before they emerge from the shadows.

Reply via email to