Proven C Book한국어 GitHub

Appendix C — Implicit conversions in summary

A compression of chapter 29′s rules into tables.

Integer promotion

When bool, char, signed char, unsigned char, short, unsigned short or a bit-field takes part in arithmetic:

That is, arithmetic does not happen on a type narrower than int.

The usual arithmetic conversions (the common type of two operands)

  1. If one side is long double → both long double
  2. Otherwise if one side is double → both double
  3. Otherwise if one side is float → both float
  4. If both are integers → after promoting each:

    • if the signedness is the same → the wider side
    • if the unsigned side is wider or equal → the unsigned side
    • if the signed side is wider and holds all of the other’s values → the signed side
    • otherwise → the unsigned edition of the signed side

The practical summary: when they mix, to the wider side; when the widths are equal, the unsigned side wins. Avoid comparisons of mixed signedness (turn the warnings on and the compiler points them out).

The default promotions of variadic arguments

Arguments crossing into a place with no type in the prototype (...):

So printf has no float-specific format, and %f takes a double (chapters 19, 25 and 58).

Integer conversion rank (the criterion of the conversion rules)

The order used when the usual arithmetic conversions choose “the wider side”. Higher is above.

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

Three things must be distinguished.

char, signed char and unsigned char have the same rank. Having the same width, the three sit in one slot.

bool’s rank is lower than those. The standard pins bool below every signed integer type in rank.

③ Rank is not width. At the same width the ranks of the unsigned and the signed side are the same, and then the unsigned side wins in the usual arithmetic conversions. That is why -1 < 1u is false — -1 turns into a huge unsigned value (chapter 29). Ranks can differ at the same width (where an implementation provides extended integer types), and at the same rank the signedness settles the result.

Which conversion calls down which danger

conversionwhat happensdanger
signed → unsignedthe two’s complement value is reinterpreted as it isa negative becomes a huge value
unsigned → signedas it is if it fits, otherwise implementation-definedthe value changes at the boundary
wide integer → narrow unsigned integerthe remainder modulo 2𝑁 (defined)quiet loss of value
wide integer → narrow signed integeras it is if it fits, otherwise implementation-definedso it stands in C23 too
integer → realrounded to the nearest valueloss of precision for large integers (chapter 8)
real → integerthe fractional part is discarded (towards 0)outside the range it is outside the contract
doublefloatthe precision is reducedrounding error
pointer → void *losslessonly the type information is lost
void * → another pointerlosslessoutside the contract if the alignment does not match (chapter 37)
integer → pointerimplementation-definedthe provenance is lost (chapter 14)

Table 99.1

A list of the places quiet conversions happen

Implicit conversion happens without asking in the following places.

Other conversions often met