The (optional) fixed-width types intN_t
, and also various other types like uint_fast16_t
, uintmax_t
and intptr_t
, are aliases for one of the built-in integral types. You don't know what the actual types they're aliasing are, only that they must meet the documented constraints.
In the case of "exactly 8 bits", the constraints don't leave much room, though, and the only integral types that can be 8 bits wide are the char
types (recall there are three of them). So int8_t
, if it exists, must be an alias for either char
or signed char
.
Unrelatedly, iostreams defines overloads for operator<<
for the all character types which have the effect of writing the value directly to the output rather than formatting the integer as a decimal string (this is so that you can conveniently write std::cout << 'a'
), and this overload is also used for int8_t
-- overload resolution works on types, not on type names. (It is perhaps regrettable that there is an special ostream overload for signed char
; it might have been nicer to only provide the overload for char
and treat the other types like ordinary integers.) That's why you see the value printed as a character in your system's encoding.
If you want to print the value formatted as a string, just convert it to one of the wider integral types. For example, you can apply the standard promotions with the unary plus: int8_t x = 5; std::cout << +x;
std::is_same<std::int8_t, signed char>::value
– Hamill