cintegerlanguage-lawyerconversion-rank

Conversion rank of extended unsigned integer type


The conversion rank is defined in 6.3.1.1/1:

Every integer type has an integer conversion rank defined as follows:

— No two signed integer types shall have the same rank, even if they have the same representation.

— The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.

— The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.

— The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.

— The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.

— The rank of char shall equal the rank of signed char and unsigned char .

— The rank of _Bool shall be less than the rank of all other standard integer types.

— The rank of any enumerated type shall equal the rank of the compatible integer type (see 6.7.2.2).

— The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined, but still subject to the other rules for determining the integer conversion rank.

— For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.

There is a rule regarding a signed integer type:

The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.

QUESTION: Can an extended unsigned integer type with higher precision has lesser integer conversion rank?

Consider size_t and unsigned int. The first one is an extended integer type and in case size_t has lesser integer conversion rank than unsigned int then integer promotion is applied to size_t which may result in precision loss.


Solution

  • First of all, size_t is commonly not an extended integer type, but a typedef for an otherwise existing unsigned integer type type. It can, even then, have rank less than or greater than that of unsigned int. Secondly, the standard says in 6.3.1.1p3 that

    1. The integer promotions preserve value including sign.

    I.e. it follows that an unsigned integer type with more value bits than unsigned int cannot have a conversion rank less than unsigned int, otherwise that clause on integer promotions would not be valid.

    And, of course, as Kamil Cuk points out, 6.2.5p8 nails it:

    8 For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.


    I believe you're confusing the usual arithmetic conversions with the integer promotions. Usual arithmetic conversions can lose the sign and modify the value of a negative signed integer.