Dans le livre "Complete Reference of C", il est mentionné que char
est non signé par défaut.
Mais j'essaie de vérifier cela avec GCC et Visual Studio. Il le prend comme signé par défaut.
Laquelle est correcte?
Le livre est faux. La norme ne spécifie pas si plain char
est signé ou non.
En fait, la norme définit trois types distincts: char
, signed char
, et unsigned char
. Si vous #include <limits.h>
puis regardez CHAR_MIN
, vous pouvez savoir si plain char
est signed
ou unsigned
(si CHAR_MIN
est inférieur à 0 ou égal à 0), mais même dans ce cas, trois types sont distincts en ce qui concerne le standard.
Notez que char
est spécial de cette façon. Si vous déclarez une variable comme int
, cela équivaut à 100% à la déclarer comme signed int
. Ceci est toujours vrai pour tous les compilateurs et architectures.
Comme Alok le fait remarquer, la norme laisse cela à la mise en œuvre.
Pour gcc, la valeur par défaut est signée, mais vous pouvez le modifier avec -funsigned-char
. remarque: pour gcc dans Android NDK, la valeur par défaut est unsigned. Vous pouvez également demander explicitement des caractères signés avec -fsigned-char
.
Sur MSVC, la valeur par défaut est signée mais vous pouvez le modifier avec /J
.
brouillon C99 N1256 6.2.5/15 "Types" a ceci à dire à propos de la signature de type char
:
L'implémentation doit définir char pour avoir la même plage, représentation et comportement que char signé ou non signé.
et dans une note de bas de page:
CHAR_MIN
, défini dans<limits.h>
, aura l'une des valeurs0
ouSCHAR_MIN
, et ceci peut être utilisé pour distinguer les deux options. Quel que soit le choix effectué,char
est un type distinct des deux autres et n'est compatible ni avec l'autre.
Selon le livre The C Programming Language de Dennis Ritchie, qui est le livre standard de facto pour ANSI C, les caractères simples signés ou non signés dépendent de la machine, mais les caractères imprimables sont toujours positifs.
Selon la norme C, la signature du caractère brut est "implémentation définie".
En général, les implémenteurs ont choisi celle qui était la plus efficace pour implémenter leur architecture. Sur les systèmes x86, char est généralement signé. Sur les systèmes à armement, il est généralement non signé (Apple iOS est une exception).
Selon "Le langage de programmation C++" de Bjarne Stroustrup, char
est "implémentation définie". Ça peut être signed char
ou unsigned char
en fonction de la mise en œuvre. Vous pouvez vérifier si char
est signé ou non en utilisant std::numeric_limits<char>::is_signed
.
Nous savons maintenant que la norme laisse cela à la mise en œuvre.
Mais comment vérifier un type est signed
ou unsigned
, tel que char
?
J'ai écrit une macro pour faire ceci:
#define IS_UNSIGNED(t) ((t)~1 > 0)
et le tester avec gcc
, clang
et cl
. Mais je ne suis pas sûr que ce soit toujours sûr pour les autres cas.