char
is a fundamental type. wchar_t
evolved as first a library solution (in C), and then became a built in type with an underlying type, corresponding to the type that earlier was used to typedef
it:
C++11 $3.9.1/5
” Type wchar_t
shall have the same
size, signedness, and alignment requirements (3.11) as one of the other integral types, called its underlying
type.
This explains why you cannot change the signedness of wchar_t
, but it does not explain why there is a char
type with unspecified signedness.
Also, the choice of signed char
that most compilers default to, is impractical for several reasons. One reason is that the negative values are annoying and generally have to be cast to unsigned in order to compare them. Another reason is that the C character classification functions require non-negative values (except when being passed EOF
). A third reason is that on old magnitude-and-sign or one's complement machines there's one unusable value.
There may be some explanation of that in Stroustrup's “The design and evolution of C++”, but I doubt it.
It sounds like frozen history, something that at one point made some kind of sense, for the technology at the time.
wchar_t
is allowed to be signed or unsigned per [basic.fundamental]. – Instrumentwchar_t
differs fromchar
in thatchar
may be a signed type or an unsigned type while still being a type that is not equivalent tosigned char
andunsigned char
, unlikewchar_t
which may be a signed or unsigned type with no way to specify a separatesigned wchar_t
orunsigned wchar_t
type. – Weaklingwchar_t
andsigned wchar_t
are the same. Interesting that it doesn't make the same complaint aboutchar
. – Leoni