Require exact-width integer type interfaces

 org: ISO/IEC JCT1/SC22/WG14 document: N2821 target: IS 9899:2023 version: 0 date: 2021-9-19 license: CC BY

Introduction

C23 already simplifies the integer model in two important aspects. First, it only has two’s complement as the sign representation of integer types and, second, we also do not allow sign bits to be masked out for a corresponding unsigned integer type. So we have gained guarantees for the homogeneity of integer representations and for the absence of padding in a general framework.

Besides bool, most platforms have standard or extended integer types without padding bits, so usually they can be used (and are used) through the typedefs of the form [u]intN_t. There is no apparent technical reason that such integer types are not exposed as exact-width integer types, so for the sake of the programmer’s comfort we propose to make them mandatory where they may.

On the other hand the [u]intmax_t ABI freeze inhibits any progress on platforms that want to add new, wider, integer types even if they fulfill the requirements for [u]intN_t. The notorious example for this is gcc. On most modern platforms it has type __int128_t and the corresponding unsigned type (soft or hard), but this type cannot be added to the platform as an extended integer type because of the ABI freeze.

The demand for integer types with 128 and 256 bits is increasing, other languages start to have them among their required types. We should not wait another normalization cycle (12 years so far) to make this happen. Thus we propose to allow such extended types in a restricted setting, namely where they are such that they can (and must with the above) be interfaced as exact-width integer type.

Changes

Change in 7.20.1.1 (Exact-width integer types) p3

These types are optional. However, ifIf an implementation provides standard or extended integer types with widthsa width of 8, 16, 32, or 64 N, and no padding bits, it shall define the corresponding typedef names.

Rationale:

Since C23 reforms the possible integer types, there is not much reason that an implementation that has such types should not announce them through these interfaces. Most implementations probably to do so anyhow; their addition to the header is of minimal overhead.

NB: The insertion of standard or extended ensures consistency with the new bit-precise integer types that are added in C23.

Impact:

The impact for implementations should be minimal. This change only requires them to newly publish a type (that has not a width of 8, 16, 32 or 64) and all depending macros in a standardized form that is already present on the platform either as standard integer type (very unlikely) or as extended integer type (currently not heard of). The only additional implementation effort could be for an extended type for which there would not yet be specifiers for formatted IO. As these extended types are never heard of up to now, existence of a platform that such a lacks such specifiers is very unlikely.

No ABI changes are intended.

It only changes perception of the platform for user code if that code is recompiled and queries for types outside the spectrum that the header offers so far, most likely for values for N or 24, 48, 96, or 128. This impact is intended.

Change in 7.20.1.5 (Greatest-width integer types) p1

The following type designates a signed integer type capable of representing any value of any signed integer type with the possible exception of extended integer types that have a width N that is greater than LLONG_WIDTH and that are referred by the type definitions for intN_t:

intmax_t

The following type designates the unsigned integer type capable of representing any value of any unsigned integer type that corresponds to intmax_tFNT1:

uintmax_t

These types are required.

FNT1 Thus this type is capable of representing any value of any unsigned integer type with the possible exception of extended integer types that have a width N that is greater than ULLONG_WIDTH and that are referred by the type definitions for uintN_t.

Rationale:

Because [u]intmax_t is part of platform ABIs, currently implementations are stuck on their current integer model. They can’t add new wider integer types on new sub-architectures and can’t even offer soft-emulations for such types.

WG14 has discussed this a lot over the last years and partially taken action to accommodate that failure; in particular C23 will offer possibilities in printf and scanf to input and output types that are wider than [u]intmax_t. This addition makes it now possible to add extended types and macros that match the requirements of [u]intN_t.

The fact that platforms are not extendable for new integer types has not been completely addressed, yet. We should not delay that another 12 years.

Impact:

Because it only widens permissions for implementations, the change has no impact on existing implementations or user code.

In contrast to that, platforms that want to add new integer types without padding that are wider than ULLONG_WIDTH, e.g via a soft-emulation, may do so and interface them as uintN_t.

• The new conversion specifications then allow such platforms to print or scan these types; PRI and SCN macros can point to the corresponding formats.

• Integer constants for these types can be implemented in the usual way. Instead of producing an error when they are larger than ULLONG_MAX, e.g, the platform just has to switch type to their wider extended type. Such constants are valid preprocessor numbers. They would simply not be available as constants in preprocessor conditionals, but with the introduction of the [U]INT..._WIDTH feature macros a need for that in new code should seldom arise.

Questions to WG14

1. Shall we integrate Change 2.1 into C23?

2. Shall we integrate Change 2.2 into C23?