Skip to content

Latest commit

 

History

History
57 lines (35 loc) · 1.71 KB

conversions.mkd

File metadata and controls

57 lines (35 loc) · 1.71 KB

Conversions

Often people claim that integer promotions and usual arithmetic conversions are difficult. As expressed in the ISO C standard, this is certainly the case, but the rules are really very simple:

C orders all integer types by rank:

  • bool
  • char/signed char/unsigned char
  • short/unsigned short
  • int/unsigned int
  • long/unsigned long
  • long long/unsigned long long

The resulting type after integer promotion is 'int' or 'unsigned int'. It is the latter only when 'int' can not represent all values of the original type. Essentially, small types are up-converted to the size of a machine word.

The usual arithmetic conversion define the type of an arithmetic operation given the types of its arguments after promotion. It is an integer type with a rank corresponding to the highest rank of its arguments (after promotion) and it is the signed type if and only if the signed type can represent all values of the original types.

Taken together, the rule is simple:

The result type has rank corresponding to the maximum of the rank of the two arguments and the rank of int. The type is signed iff it can represent all values of the types of the arguments and is unsigned otherwise.

One can compute the type with this simple logic:

  // compute rank after integer promotion and usual arithmetic conversion
  #define UAC_RANK(A, B)	MAX(MAX(RANK(A), RANK(B)), RANK(int))

  // signed type is used when it can represent all values of the original types
  #define SGN_OK(A, B) (MAXVAL(TYPE(UAC_RANK(A, B))) >= MAX(MAXVAL(A), MAXVAL(B)))

  // type after usual arithmetic conversion
  #define UAC(A, B) TYPE_CHOOSE(SGN_OK(A, B), TYPE(UAC_RANK(A, B)), TYPE_UNSIGNED(UAC_RANK(A, B)))