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.
Modify C23 7.21.1 paragraph 3:
ptrdiff_twhich is the signed integer type other than a bit-precise signed integer type of the result of subtracting two pointers;
size_twhich is the unsigned integer type other than a bit-precise unsigned integer type of the result of the
sizeofoperator;...
wchar_twhich is a
nsigned 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_twhich 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_twhich is a
nsigned 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 subsequentWEOFdescription);
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.