Reputation: 19140
Reading C++17 draft §6.9.1/5:
Types
char16_t
andchar32_t
denote distinct types with the same size, signedness, and alignment asuint_least16_t
anduint_least32_t
, respectively, in<cstdint>
, called the underlying types.
Now referring to C11 draft §7.20.1.2/2, which is the reference for the C library inheritance:
The typedef name
uint_leastN_t
designates an unsigned integer type with a width of at least N , such that no unsigned integer type with lesser size has at least the specified width. Thus,uint_least16_t
denotes an unsigned integer type with a width of at least 16 bits.
Note the "at least" part. This means that char16_t
may actually have e.g. 32 bits, making an array of char16_t
a bad representation of a UTF-16 raw data. In this case writing such an array to a binary file would result in valid code units alternating with U+0000 characters.
Is there a good reason for char16_t
to be defined in terms of uint_least16_t
instead of uint16_t
? Or is it simply a defect in the standard?
Upvotes: 3
Views: 1316
Reputation: 76448
First, as the name suggests, uint_least16_t
is required to be the smallest size that can hold 16 bits. On a system with both 16- and 32-bit integers, it cannot be 32 bits.
Second, uint16_t
is not required to exist. It's only there on systems that have a 16-bit integer type. Granted, those are quite common, but C and C++ are designed to impose minimal constraints on the hardware that they can target, and there are systems that don't have a 16-bit integer type.
On a system that does have a 16-bit integer type, uint16_t
will be 16 bits wide (duh...), and uint_least16_t
will also be 16 bits wide. On a system that doesn't have a 16-bit integer type, uint16_t
won't exist, and uint_least16_t
will. For code that needs to store values in a range that's representable in 16 bits, using uint_least16_t
is portable. For code that needs to store exactly 16 bits (which is rare), uint16_t
is the way to go.
Upvotes: 5
Reputation: 238421
This makes it possible to use char16_t
on systems where byte size is not a factor of 16 (for example 32 bit byte, or 9 bit byte) . Such systems can have uint_least16_t
but not uint16_t
.
Upvotes: 4