Adloun

Une comparaison qui rend faux

Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 4 — Discipline de programmation, validation et test

Énoncé

Ce programme affiche-t-il vrai ou faux ? Et que fait la boucle ?


int a = -1;
unsigned int b = 1;
printf("%s\n", (a < b) ? "vrai" : "faux");

unsigned int m = 0;
for (unsigned int i = 0; i < m - 1; i = i + 1) { /* ... */ }

Corrigé

Il affiche faux, et la boucle tourne fois.


-1 < 1u           ? FAUX
-1 == 4294967295u ? vrai
m - 1 avec m = 0u = 4294967295

Pourquoi. Quand une comparaison mêle un int et un unsigned int de même largeur, les conversions arithmétiques usuelles convertissent le signé vers le non signé — et non l'inverse. Le devient donc , qui n'est pas inférieur à . La seconde ligne mesurée le confirme : et sont le même motif de bits, et la comparaison d'égalité les déclare égaux.

De même, sur un unsigned int ne vaut pas : l'arithmétique non signée est modulaire, elle « repasse » par le haut. La borne de boucle devient donc gigantesque au lieu d'être négative, et la boucle qu'on croyait vide s'exécute quatre milliards de fois.

Le compilateur avertit, si on le laisse parler :


warning: comparison of integers of different signs: 'int' and 'unsigned int'
         [-Wsign-compare]

-Wsign-compare est inclus dans -Wextra. C'est une des meilleures raisons de l'employer.

En pratique — La règle simple

On n'emploie un type non signé que lorsque le comportement modulaire est voulu — masques de bits, hachage, arithmétique circulaire. Pour une taille, un indice, un compteur, on prend un int (ou un ptrdiff_t), même si « une taille ne peut pas être négative » : cet argument est exactement celui qui conduit à écrire i &lt; taille - 1 et à découvrir quatre milliards de tours. size_t, rendu par sizeof et strlen, est non signé : c'est là qu'il faut être vigilant, et écrire i + 1 &lt; taille plutôt que i &lt; taille - 1.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.