The conversion ranks of signed integer types and bit-precise signed integer types is defined in C23 §6.3.1.1 as follows:
- The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
[...]
- The rank of a bit-precise signed integer type shall be greater than the rank of any standard integer type with less width or any bit-precise integer type with less width.
Why is the first definition worded in terms of precision, while the second is worded in terms of width, even though both definitions concern signed integers?
Why is the rank of a bit-precise signed integer defined in terms of standard integer types and bit-precise integer types, rather than standard signed integer types and bit-precise signed integer types?
While I could not find any clarification in the proposal document for bit-precise integers, I noticed that an earlier draft of the proposal (N2646) had originally defined the rank of a bit-precise integer in terms of precision:
A _BitInt type has a greater rank than any integer type with less precision [...]
But this was later changed in a newer draft (N2709) to be worded in terms of width:
A _BitInt type has a greater rank than any standard integer type with less width. [...]
There is a slight difference between precision and width.
The width of an integer type includes both value bits and sign bits.
The precision of an integer type includes only value bits.
For unsigned types, these values are the same. For signed types, the width is larger by 1.
The wording of the first quoted passage:
The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
Goes back to at least C99, while the second:
The rank of a bit-precise signed integer type shall be greater than the rank of any standard integer type with less width or any bit-precise integer type with less width.
Is new to C23. As an example, given a 16 bit short
, _BitInt(17)
would have higher rank because it's width of 17 is greater than the 16 of short
but _BitInt(16)
would not have higher rank.
6.3.1.1p1 also contains this:
The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width or bit-precise integer type with the same width.
Which would mean that short
has higher rank than _BitInt(16)
since both have the same width.
If the following passage was retained:
_BitInt type has a greater rank than any integer type with less precision
It would mean that unsigned _BitInt(16)
with precision 16 would have higher rank that short
with precision 15. And because of the following in 6.3.1.1p1:
The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
That would mean that _BitInt(16)
would have higher rank than short
.
So the wording was changed between drafts from precision to width with regard to bit-precise types to avoid ambiguity. And because width is the same for a signed and corresponding unsigned type, the "signed" qualifier could be dropped.