Issue 1043: Issues with library integer types

Authors: Jay Ghiron
Date: 2026-04-08
Submitted against: C23
Status: Open
Cross-references: 1021

Some standard library types do not properly constrain what integer types are allowed. For example:

#include<stddef.h>
enum E:size_t{e};

In C23, if size_t were a bit-precise unsigned integer type then this program would have a constraint violation. In C2Y now that N3705 is accepted, this program would be fine regardless. The functions in <stdbit.h> only work with some bit-precise unsigned integer types, and the functions in <stdckdint.h> never with any bit-precise integer types. Therefore if size_t were a bit-precise unsigned integer type it might not be possible to use <stdbit.h> with size_t and it would never be possible to use <stdckdint.h> with size_t. Bit-precise integer types also have different rules in promotions, so code that relied on integer promotions happening before C23 would be broken.

The same issues also exist for many other types. sig_atomic_t can be char, a bit-precise integer type, an enumerated type, or a volatile qualified version of any of those types. ptrdiff_t can be a bit-precise signed integer type. wchar_t can be char, a bit-precise integer type, or an enumerated type. wint_t can be a bit-precise integer type, or an enumerated type if issue 1021 is resolved as enumerated types possibly being the results of integer promotions. uint_least1_t and uint_fast1_t can both be defined as bool, though this is forbidden in C2Y now that N3747 is accepted.

The types time_t, clock_t, wctrans_t, and wctype_t can be any integer type but they can also be types other than integer types so it does not seem important to restrict which integer types they can be. memory_order is defined to be an enumerated type with no restrictions on its underlying type, though that does not seem important to restrict. Code using time_t or clock_t could also assume that integer promotions would apply if they were not floating types and had widths less than the width of int, but that does not seem important.

Suggested correction

Modify C23 7.21.1 paragraph 3:

ptrdiff_t

which is the signed integer type other than a bit-precise signed integer type of the result of subtracting two pointers;

size_t

which is the unsigned integer type other than a bit-precise unsigned integer type of the result of the sizeof operator;

...

wchar_t

which is an signed or unsigned integer type other than a bit-precise integer type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales; the null character shall have the code value zero.

Note: C23 6.4.5.5 paragraph 9 already contains the wording "the unsigned type corresponding to wchar_t" which would not make sense if wchar_t were defined as char or an enumerated type.

Modify C23 7.14.1 paragraph 2:

sig_atomic_t

which is the (possibly volatile-qualified) signed or unsigned integer type other than a bit-precise integer type of an object that can be accessed as an atomic entity, even in the presence of asynchronous interrupts.

Modify C23 7.31.1 paragraph 3:

wint_t

which is an signed or unsigned integer type other than a bit-precise integer type unchanged by default argument promotions that can hold any value corresponding to members of the extended character set, as well as at least one value that does not correspond to any member of the extended character set (see subsequent WEOF description);

Modify C23 7.22.1 paragraph 4:

None of the types shall be defined as a synonym for a bit-precise integer type or bool.

Note: This last change does not need to be applied in C2Y.