A narrow value changes before arithmetic
Consider `signed short b = -1;`. Although `b` is stored as a narrow integer type, C promotes it to `signed int` before arithmetic or comparison. Likewise, `char` and `bool` represent characters and truth values, but behave as numbers in these expressions. section 5.2
A narrow type is a C integer or character type that does not participate directly in arithmetic. Before evaluation, C promotes its value to a wider type—normally `signed int` with the same value on realistic platforms. The C standard constrains, but does not fully prescribe, the precision and ranges of the underlying integer types. section 5.2
Use narrow types for representation, not ordinary calculation:
- Use `char` for characters and strings. section 12.5
- Use `unsigned char` to inspect object bytes, without performing arithmetic on those values. section 12.5
- Choose narrow storage for very large arrays of small values when saving memory matters. section 12.5
- Avoid narrow conversions and narrow operands in arithmetic; conversions can lose information, as with an oversized value assigned to `unsigned short`. section 5.4
Table 5.1. Base types according to the four main type classes. Types with a gray background don’t allow for arithmetic; they are promoted before doing arithmetic. Type char is special since it can be unsigned or signed, depending on the platform. All types in this table are considered to be distinct types, even if they have the same class and precision. (view table figure)
| Class |
Systematic name |
Other name |
Rank |
|
|---|---|---|---|---|
| Integers | Unsigned | _Bool | bool | 0 |
| unsigned char | 1 | |||
| unsigned short | 2 | |||
| unsigned int | unsigned | 3 | ||
| unsigned long | 4 | |||
| unsigned long long | 5 | |||
| [Un]signed | char | 1 | ||
| signed char | 1 | |||
| signed short | short | 2 | ||
| Signed | signed int | signed or int | 3 | |
| signed long | long | 4 | ||
| signed long long | long long | 5 | ||
| Floating point | Real | float | ||
| double | ||||
| long double | ||||
| Complex | float _Complex | float complex | ||
| double _Complex | double complex | |||
| long double _Complex | long double complex | |||
Use the base-type table to compare promoted types with unpromoted integer, character, Boolean, floating-point, and complex types. section 5.2

