ILP64 is problematic for existing code: there is lots of stuff like hashcode computations using uint32_t with multiplications, relying on the C standard guaranteeing wraparound for unsigned overflows. But with 64-bit int, uint32_t will promote to a signed int, and overflows will thus be undefined behavior. This problem already exists with uint16_t multiplications on current architectures, but moving the problem to uint32_t will cause trouble for a lot of existing code that thought using fixed-size types like uint32_t would be safe.
I chose to deal with this problem by doing a "pointless" operation to force a promotion to at least unsigned int. For example:
uint16_t x = 0xFFFF;
uint16_t y = 0xFFFF;
uint16_t z = (uint16_t)((x + 0U) * (y + 0U));
This piece of code will work on any machine, such as: (uint16_t = unsigned short = 16 bits, uint32_t = unsigned int = 32 bits); (uint16_t = unsigned short = unsigned int = 16 bits, uint32_t = unsigned long = 32 bits).Wrong. You mentally casted each operand to int16_t before subsequently casting to int32_t. The first step is unjustified.
The correct calculation according to the C standard is: (int32_t)0xFFFF * (int32_t)0xFFFF, which definitely overflows.
Yeah, except that multiplying two 32-bit values, recast as 64-bit signed integers, will not overflow. Even adding another 32-bit value to this product will not overflow. Throw in the final cast to uint32_t to throw away the upper sign bits, and you get the identical result.
Factually wrong. Consider: (int64_t)0xFFFFFFFF * (int64_t)0xFFFFFFFF. It definitely overflows.
That's not how I interpret section 3.2 in the standard[1]. Figure 1 seems quite explicit in how a single and a double should be encoded. The section on extended values specify they can be encoded in an implementation-depended manner, which makes the case stronger IMO.
edit: I note that in the 2008 revision[2], it's more explicitly mentioned that the specified encoding is a binary interchange format. So that's a lot more specific than the original.
And of course, if you accept the network byte order as the one intended for the interchange, then IEEE-754 mandates big-endian encoding.
>Only in C23. It was explicitly rejected for C++ 23 (and C++ 26 too, I believe).
It was added in C++20[0], see the note[1] "This is also known as two's complement representation".
[0] https://timsong-cpp.github.io/cppwp/n4868/basic.fundamental#...
[1] https://timsong-cpp.github.io/cppwp/n4868/basic.fundamental#...