El strcmp(a,b) est censée retourner
-
<0
si string a < string b
-
>0
si string a > string b
-
0
si string a == string b
Le test est en fait effectué sur le premier caractère qui est différent dans les deux chaînes au même endroit (0, le terminateur de la chaîne, fonctionne également).
Ici, puisque la fonction prend deux uint8_t
(unsigned char), le développeur s'inquiétait probablement du fait qu'une comparaison entre deux unsigned chars donnerait un nombre entre 0
y 255
Par conséquent, une valeur négative ne sera jamais renvoyée. Par exemple, 118 - 236
rendrait -118
mais sur 8 bits, il renvoie 138
.
Ainsi, le programmeur a décidé de faire un casting en int_16
, nombre entier signé (16 bits).
Cela aurait pu fonctionner, et étant donné les valeurs négatives/positives correctes (à condition que la fonction retourne int_16
au lieu de int_8
).
(*mise à jour : commentaire de @zwol ci-dessous, la promotion de l'entier est inévitable, donc ceci int16_t
la coulée n'est pas nécessaire)
Toutefois, la version finale int_8
La distribution rompt la logique. Puisque les valeurs retournées peuvent être de -255
a 255
certaines de ces valeurs verront leur signe inversé après le passage en int_8
.
Par exemple, en faisant 255 - 0
donne le positif 255
(sur 16 bits, tous les 8 bits inférieurs à 1, le MSB à 0) mais dans la int_8
monde (int signé de 8 bits), c'est négatif, -1
puisque nous n'avons que les 8 derniers bits bas en binaire. 11111111
ou décimal -1
.
Ce n'est certainement pas un bon exemple de programmation.
Ce fonction de travail d'Apple est meilleur
for ( ; *s1 == *s2; s1++, s2++)
if (*s1 == '\0')
return 0;
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
(Linux le fait en code assembleur...)