When is uint8_t ≠ unsigned char?

c, c++, types, uint8t, unsigned-char

Solution

If it exists, `uint8_t` must always have the same width as `unsigned char`. However, it need not be the same type; it may be a distinct extended integer type. It also need not have the same representation as `unsigned char`; for instance, the bits could be interpreted in the opposite order. This is a silly example, but it makes more sense for `int8_t`, where `signed char` might be ones complement or sign-magnitude while `int8_t` is required to be twos complement.

One further "advantage" of using a non-char extended integer type for `uint8_t` even on "normal" systems is C's aliasing rules. Character types are allowed to alias anything, which prevents the compiler from heavily optimizing functions that use both character pointers and pointers to other types, unless the `restrict` keyword has been applied well. However, even if `uint8_t` has the exact same size and representation as `unsigned char`, if the implementation made it a distinct, non-character type, the aliasing rules would not apply to it, and the compiler could assume that objects of types `uint8_t` and `int`, for example, can never alias.

Problem

According to C and C++, `CHAR_BIT >= 8`. But whenever `CHAR_BIT > 8`, `uint8_t` can't even be represented as 8 bits. It must be larger, because `CHAR_BIT` is the minimum number of bits for any data type on the system. On what kind of a system can `uint8_t` be legally defined to be a type other than `unsigned char`? (If the answer is different for C and C++ then I'd like to know both.)

Original source

Related problems