On Wed, 29 Mar 2023 at 10:50, Giuseppe D'Angelo via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Il 29/03/23 11:15, Timur Doumler via Std-Proposals ha scritto:
>
> Do I understand it correctly that the primary motivation for this change
> in C23 and C++23 was that changing uintmax_t would be an ABI break,
> which is deemed unacceptable for the major compiler vendors?

Changing uintmax_t would be an ABI break. The change in C++23 is to
actually allow implementations to actually offer __int128 as an extended
integer type, while keeping e.g. a 64 bit intmax_t. Otherwise, they
couldn't do that: the moment __int128 exists as an integer type,
intmax_t needs to widen, and break ABI.

It still sounds like a terrible idea to me. What's the point of intmax_t
if it's not capable of faithfully representing values of *all* integer
types? I'd rather see intmax_t deprecated than breaking completely
reasonable code:

>   void f(std::signed_integral auto x)
>   {
>     std::intmax_t v{x}; // this should *always* be well-formed and never lose data
>   }

The solution is simple:
intmx_t is not the maximum width integer type, it's the maximum width integer type that has C APIs for working with it.

So it's the widest type that has an overload of std::div. Wider types might be available, but there is no guarantee  you can use them with std::div.

Just stop thinking the "max" means "maximum width, period" and see it as "maximum width with libc support".
 

> Because if the ABI issue didn't exist, it would indeed seem
> *conceptually* more correct to have __uint128_t be an integer type and
> uintmax_t to be 128 bit, would it not?

Right, but this is now a question for compiler vendors -- why do they
not consider __int128 an extended integer type at all (at least, in
strict mode)?

E.g. GCC https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

Was it just for the intmax incompatibility?

Yes.

It is impossible to meet all three of these constraints and conform to the standard:

- intmax_t is the widest integral type
- __int128 is an integral type
- stable ABI

The choice is to be non-conforming (which libc++ does) or break one of the three constraints.

In C23 and C++23 the first constraint has been weakened, so that libc++ is now conforming, and a future release of GCC will define is_integral_v<__int128> as true in strict mode.