int main(void)
{
unsigned int i = 0;
if (i < -1 )
printf("Bizarre, bizarre ...\n");
else printf ("Tout semble normal\n");
}
imprimera le message Bizarre, bizarre ..., pouvant laisser croire que
pour le langage C,
L'explication est la suivante : l'opérateur
a un opérande de type
unsigned int (la variable i), et un autre opérande de type
int (la constante -1).
D'après le tableau des conversions donné ci-dessus, on voit que dans un tel
cas, les opérandes sont convertis en unsigned int.
Le compilateur génère donc une comparaison non signée entre 0 et 4294967295
(puisque -1 = 0xffffffff = 4294967295), d'où le résultat.
Pour que tout rentre dans l'ordre, il suffit d'utiliser l'opérateur de conversion pour prévenir le compilateur de ce qu'on veut faire :
int main(void)
{
unsigned int i = 0;
if ((int) i < -1 ) /* comparaison entre deux int */
printf("Bizarre, bizarre ...\n");
else printf ("Tout semble normal\n");
}
Là où tout se complique c'est qu'on peut utiliser des entiers non signés sans le savoir ! Considérons le programme suivant :
int main(void)
{
if (sizeof(int) < -1)
printf("Bizarre, bizarre ...\n");
else printf ("Tout semble normal\n");
}
le lecteur a sans doute deviné qu'il va imprimer le message Bizarre,
bizarre ..., et cependant les entiers n'ont pas une longueur négative !
L'explication est la suivante :
l'opérateur sizeof rend une valeur dont le type est non signé.
Voici ce que dit exactement la norme : « La valeur du résultat [ de
sizeof ] dépend de l'implémentation, et son type (un type entier
non signé) est size_t qui est définit dans le fichier d'include
stddef.h ».
Dans notre exemple, le compilateur a généré une comparaison non signée entre
4 (sizeof(int)) et