Bienvenue à promotion entière . Si je peux citer le site web :
Si un int peut représenter toutes les valeurs du type original, la valeur est convertie en int ; sinon, elle est convertie en int non signé. C'est ce qu'on appelle les promotions d'entiers. Tous les autres types sont inchangés par les promotions d'entiers.
Le langage C peut être vraiment déroutant lorsque vous effectuez des comparaisons de ce type. J'ai récemment laissé perplexe certains de mes amis programmeurs non-C avec la taquinerie suivante :
#include <stdio.h>
#include <string.h>
int main()
{
char* string = "One looooooooooong string";
printf("%d\n", strlen(string));
if (strlen(string) < -1) printf("This cannot be happening :(");
return 0;
}
Ce qui, en effet, imprime This cannot be happening :(
et démontre apparemment que 25 est plus petit que -1 !
Ce qui se passe en dessous cependant, c'est que -1 est représenté comme un nombre entier non signé qui, en raison de la représentation des bits sous-jacents, est égal à 4294967295 sur un système 32 bits. Et naturellement, 25 est plus petit que 4294967295.
Cependant, si nous couchons explicitement le size_t
retourné par strlen
comme un nombre entier signé :
if ((int)(strlen(string)) < -1)
Ensuite, elle comparera 25 contre -1 et tout ira bien pour le monde.
Un bon compilateur devrait vous avertir de la comparaison entre un entier non signé et signé et pourtant, il est toujours si facile de passer à côté (surtout si vous n'activez pas les avertissements).
Cela est particulièrement déroutant pour les programmeurs Java, car tous les types primitifs sont signés. Voici ce qu'a dit James Gosling (l'un des créateurs de Java) avait à dire sur le sujet :
Gosling : Pour moi, en tant que concepteur de langage, ce qui ne compte pas vraiment ces jours-ci, ce que "simple" a vraiment fini par signifier était de pouvoir J'attends de J. Random Developer qu'il tienne la spécification dans sa tête. Cette Cette définition dit que, par exemple, Java n'est pas - et en fait beaucoup de ces ces langages se retrouvent avec beaucoup de cas particuliers, des choses que personne que personne ne comprend vraiment. Interrogez n'importe quel développeur C sur unsigned, et vous découvrirez assez vite et vous découvrirez rapidement que presque aucun développeur C ne comprend ce qui se passe ce qui se passe avec unsigned, ce qu'est l'arithmétique unsigned. Des choses comme ça ont rendu le C complexe. La partie langage de Java est, je pense, assez simple. Les bibliothèques, vous devez les chercher.