> floating-point number types will not be discussed at all, because that mostly deals with how to analyze and handle approximation errors that stem from rounding. By contrast, integer math is a foundation of programming and computer science, and all calculations are always exact in theory (ignoring implementations issues like overflow).
Integer overflow is no mere implementation issue, any more than errors are an implementation issue with floating-point.
> Unqualified char may be signed or unsigned, which is implementation-defined.
> Unqualified short, int, long, and long long are signed. Adding the unsigned keyword makes them unsigned.
There's an additional point here that's not mentioned: char, signed char, and unsigned char are distinct types, but that's only true of char. That is, signed int describes the same type as int. You can see this using the std::is_same type-trait with a conforming compiler. Whether char behaves like a signed integer type or an unsigned integer type, depends on the platform.
> Signed numbers may be encoded in binary as two’s complement, ones’ complement, or sign-magnitude; this is implementation-defined.
This is no longer true of C++. As of C++20, signed integer types are defined to use two's complement. [0] I don't think C intends to do the same.
> Character literals (in single quotes) have the type (signed) int in C, but (signed or unsigned) char in C++.
That's not correct. In C++, the type of a character literal is simply char, never signed char nor unsigned char. As I mentioned above, whether char is signed depends on the platform, but it's always a distinct type.
> Signed division can overflow – e.g. INT_MIN / -1.
This isn't just overflow, it's undefined behaviour.
> Counting down
> Whereas an unsigned counter would require code like:
> for (unsigned int i = len; i > 0; i--) { process(array[i - 1]); }
That's one solution, but it might be a good place for a do/while loop.