En langage C, les expressions subissent souvent des conversions de types (promotion de type, conversion de type), régies par les standards :
char, short) sont automatiquement convertis en int ou unsigned int avant les opérations arithmétiques.Exemple :
unsigned short a = 65535; signed short b = -1; printf("%d ", a + b); // dépend de la conversion !
Recommandation : faites attention aux types des opérandes, surtout lors de l'utilisation d'opérations bit à bit, de longueurs de tableaux, d'indices, et évitez le mélange implicite de types signés et non signés.
Que va afficher le fragment suivant ?
unsigned int u = 1; int i = -2; printf("%d ", u + i);
Réponse : La variable i sera convertie en unsigned int, la valeur finale sera très grande, car le résultat en interne sera : 1U + (unsigned int)-2U, ce qui donnera un nombre proche de UINT_MAX (4294967295). Un nombre négatif ne sera affiché que si printf est formaté comme int, sinon ce sera une valeur indéterminée.
Histoire
Dans le calcul des valeurs moyennes d'intensité d'image,
intetunsigned intont été confondus. Les valeurs négatives étaient mal transmises à travers unsigned, produisant d'énormes nombres et provoquant un débordement du tampon d'image.
Histoire
Dans un firmware embarqué, la longueur de la chaîne était calculée avec
size_t, tandis que le tableau était indexé avecint. Lors de la vérification des conditions de dépassement de tableau, on comparaitint i >= size_t len, ce qui brisait la logique pour les longues chaînes et provoquait des bugs dans la comparaison de différents types (size_t — unsigned).
Histoire
Un développeur sur un projet financier calculait le reste de la division pour les nombres négatifs avec
%, oubliant que le signe du résultat pour des opérandes négatifs dépend de l'implémentation. Dans un environnement, le résultat était positif, dans un autre — négatif, ce qui faisait que les calculs "déraillaient" périodiquement.