Des raisons historiques, la plupart du temps.
Les Expressions de type char
sont promues int
dans la plupart des contextes (parce que beaucoup de Processeurs n'ont pas de 8-bits des opérations arithmétiques). Sur certains systèmes, l'extension du signe est le moyen le plus efficace pour ce faire, ce qui plaide pour la fabrication de plain char
signé.
D'autre part, le jeu de caractères EBCDIC a des caractères de base avec l'ensemble de bits (c'est à dire, les personnages avec des valeurs de 128 ou plus); sur CES plateformes, char
assez bien pour ne pas être signé.
L' ANSI C Justification (pour l'1989 standard) qui n'a pas beaucoup à dire sur le sujet; la section 3.1.2.5 dit:
Trois types de char sont spécifiés: signed
, en plaine, et unsigned
. Un
plaine char
peut être représenté que soit signé ou non signé, selon
lors de la mise en œuvre, comme dans la pratique antérieure. Le type signed char
a été introduit pour rendre disponible un octet signé de type entier sur
ces systèmes qui mettent en œuvre la plaine de char non signés. Pour des raisons de
la symétrie, le mot-clé signed
est admise comme partie du nom de type de
d'autres types intégraux.
En remontant plus loin, une première version de la C Manuel de Référence à partir de 1975 dit:
Un char
objet peut être utilisé partout où un int
peut-être. Dans tous les cas, l'
char
est converti en int
par la multiplication de sa signature par le haut
8 bits de la résultante entier. Ceci est cohérent avec les deux
en complément de la représentation utilisée pour les deux personnages et les nombres entiers.
(Cependant, le signe-propagation caractéristique disparaît dans d'autres
les implémentations.)
Cette description est plus spécifique à l'implémentation de ce que nous voyons dans les documents ultérieures, mais il ne reconnaissez char
peut être soit signé ou non signé. Sur les "autres applications" sur lequel "le signe de propagation disparaît", la promotion de l' char
objet d' int
aurait zéro-extension de la 8-bits de la représentation, essentiellement de la traiter comme une 8-bits non signé de la quantité. (La langue n'a pas encore l' signed
ou unsigned
mot-clé.)
C prédécesseur immédiat a été une langue appelée B. B est un sans type de langue, de sorte que la question de l' char
signé ou non signé ne s'applique pas. Pour plus d'informations sur les débuts de l'histoire de C, voir la fin de Dennis Ritchie, page d'accueil.
Comme pour ce qui se passe dans votre code (application moderne C règles):
char c = 0xff;
bool b = 0xff == c;
Si plain char
est non signé, puis l'initialisation de c
il met à la (char)0xff
, qui se compare égal à 0xff
dans la deuxième ligne. Mais si plain char
est signé, alors 0xff
(une expression de type int
) est converti en char
-- mais depuis 0xff
dépasse CHAR_MAX (en supposant CHAR_BIT==8
), le résultat est la mise en œuvre définies. Dans la plupart des implémentations, le résultat est -1
. Dans la comparaison, 0xff == c
, les deux opérandes sont convertis en int
, ce qui équivaut à 0xff == -1
ou 255 == -1
, ce qui est évidemment faux.
Une autre chose importante à noter est que l' unsigned char
, signed char
, et (brut) char
sont de trois types distincts. char
a la même représentation que soit unsigned char
ou signed char
; il est de la mise en œuvre définies par lequel il est. (D'un autre côté, signed int
et int
sont deux noms pour le même type; unsigned int
est un type distinct. (Sauf que, juste pour ajouter à la frivolité, c'est la mise en œuvre-définir si un champ de bits déclaré brut int
est signé ou non signé.))
Oui, c'est un peu le bazar, et je suis sûr qu'il aurait pu être définies différemment si C ont été conçus à partir de zéro aujourd'hui. Mais chaque révision du langage C a eu pour éviter de casser (un peu trop) du code existant, et dans une moindre mesure implémentations existantes.