I'll answer your questions in reverse order.
Does the standard specify whether this type can or will be a character type?
Short answer: int8_t
is signed char
in the most popular platforms (GCC/Intel/Clang on Linux and Visual Studio on Windows) but might be something else in others.
The long answer follows.
Section 18.4.1 of the C++11 Standard provides the synopsis of <cstdint>
which includes the following
typedef
signed integer type int8_t; //optional
Later in the same section, paragraph 2, it says
The header [<cstdint>
] defines all functions, types, and macros the same as 7.18 in the C standard.
where C standard means C99 as per 1.1/2:
C ++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:1999 Programming languages — C (hereinafter referred to as the C standard).
Hence, the definition of int8_t
is to be found in Section 7.18 of the C99 standard. More precisely, C99's Section 7.18.1.1 says
The typedef
name intN_t
designates a signed integer type with width N
, no padding bits, and a two’s complement representation. Thus, int8_t denotes a signed integer type with a width of exactly 8 bits.
In addition, C99's Section 6.2.5/4 says
There are five standard signed integer types, designated as signed char, short int, int, long int, and long long int. (These and other types may be designated in several additional ways, as described in 6.7.2.) There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types.
Finally, C99's Section 5.2.4.2.1 imposes minimum sizes for standard signed integer types. Excluding signed char
, all others are at least 16 bits long.
Therefore, int8_t
is either signed char
or an 8 bits long extended (non standard) signed integer type.
Both glibc (the GNU C library) and Visual Studio C library define int8_t
as signed char
. Intel and Clang, at least on Linux, also use libc and hence, the same applies to them. Therefore, in the most popular platforms int8_t
is signed char
.
Given this C++11 program, should I expect to see a number or a letter? Or not make expectations?
Short answer: In the most popular platforms (GCC/Intel/Clang on Linux and Visual Studio on Windows) you will certainly see the letter 'A'. In other platforms you might get see 65
though. (Thanks to DyP for pointing this out to me.)
In the sequel, all references are to the C++11 standard (current draft, N3485).
Section 27.4.1 provides the synopsis of <iostream>
, in particular, it states the declaration of cout
:
extern ostream cout;
Now, ostream
is a typedef
for a template specialization of basic_ostream
as per Section 27.7.1:
template <class charT, class traits = char_traits<charT> >
class basic_ostream;
typedef basic_ostream<char> ostream;
Section 27.7.3.6.4 provides the following declaration:
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, signed char c);
If int8_t
is signed char
then it's this overload that's going to be called. The same section also specifies that the effect of this call is printing the character (not the number).
Now, let's consider the case where int8_t
is an extended signed integer type. Obviously, the standard doesn't specify overloads of operator<<()
for non standard types but thanks to promotions and convertions one of the provided overloads might accept the call. Indeed, int
is at least 16 bits long and can represent all the values of int8_t
. Then 4.5/1 gives that int8_t
can be promoted to int
. On the other hand, 4.7/1 and 4.7/2 gives that int8_t
can be converted to signed char
. Finally, 13.3.3.1.1 yields that promotion is favored over convertion during overload resolution. Therefore, the following overload (declared in in 23.7.3.1)
basic_ostream& basic_ostream::operator<<(int n);
will be called. This means that, this code
int8_t i = 65;
std::cout << i;
will print 65
.
Update:
1. Corrected the post following DyP's comment.
2. Added the following comments on the possibility of int8_t
be a typedef
for char
.
As said, the C99 standard (Section 6.2.5/4 quoted above) defines 5 standard signed integer types (char
is not one of them) and allows implementations to add their onw which are referred as non standard signed integer types. The C++ standard reinforces that definition in Section 3.9.1/2:
There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long long int” [...] There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types.
Later, in the same section, paragraph 7 says:
Types bool
, char
, char16_t
, char32_t
, wchar_t
, and the signed and unsigned integer types are collectively called integral types. A synonym for integral type is integer type.
Therefore, char
is an integer type but char
is neither a signed integer type nor an unsigned integer type and Section 18.4.1 (quoted above) says that int8_t
, when present, is a typedef
for a signed integer type.
What might be confusing is that, depending on the implementation, char
can take the same values as a signed char
. In particular, char
might have a sign but it's still not a signed char
. This is explicitly said in Section 3.9.1/1:
[...] Plain char
, signed char
, and unsigned char
are three distinct types. [...] In any particular implementation, a plain char
object can take on either the same values as a signed char
or an unsigned char
; which one is implementation-defined.
This also implies that char
is not a signed integer type as defined by 3.9.1/2.
3. I admit that my interpretation and, specifically, the sentence "char
is neither a signed integer type nor an unsigned integer type" is a bit controversial.
To strength my case, I would like to add that Stephan T. Lavavej said the very same thing here and Johannes Schaub - litb also used the same sentence in a comment on this post.
uint8_t
is an integer type, not a character type. I expect numbers, not letters. It looks like another C++ committee faux pas (GCC 6.3.1-1 prints them as characters). The committee got it partially right withstd::byte
.std::byte
does not print as a character type (at the moment, it does not print at all. Hopefully that will be fixed in the future). – Possiblyuint8_t
is an integer type, @jww, for sure. The problem is just that all character types (andbool
) are integer types, too, for better and for worse. (The worse, in this case, being that compilers aren't smart enough to track type aliases to determine intended use cases.) – Himyaritic