Nel linguaggio C, nelle espressioni spesso avvengono conversioni di tipo (type promotion, type conversion), regolamentate dallo standard:
char, short) vengono automaticamente convertiti in int o unsigned int prima delle operazioni aritmetiche.Esempio:
unsigned short a = 65535; signed short b = -1; printf("%d\n", a + b); // dipende dalla conversione!
Raccomandazione: presta attenzione ai tipi degli operandi, specialmente quando lavori con operazioni bit, lunghezze di array, indici, e evita la mescolanza implicita di tipi firmati e non firmati.
Cosa stamperà il seguente frammento?
unsigned int u = 1; int i = -2; printf("%d\n", u + i);
Risposta: La variabile i sarà convertita in unsigned int, il valore finale diventerà molto grande, poiché il risultato sotto al cofano è: 1U + (unsigned int)-2U, che darà un numero vicino a UINT_MAX (4294967295). Sarà stampato un numero negativo solo se printf formatta come int, altrimenti spazzatura.
Storia
Nel calcolo delle medie di intensità di un'immagine sono stati scambiati
inteunsigned int. I valori negativi erano erroneamente traslati attraverso unsigned e davano numeri giganteschi, causando un overflow del buffer dell'immagine.
Storia
Nella firmware incorporata calcolavano la lunghezza della stringa tramite
size_t, mentre indicizzavano l'array tramiteint. Nella verifica della condizione di uscita dall'array confrontavanoint i >= size_t len, il che rompeva la logica per stringhe lunghe e provocava bug nel confronto di tipi diversi (size_t — unsigned).
Storia
Un sviluppatore in un progetto finanziario calcolava il resto della divisione per numeri negativi tramite
%, dimenticando che il segno del risultato per operandi negativi dipende dall'implementazione. In un ambiente il risultato era positivo, in un altro — negativo, causando occasionalmente che i calcoli "saltassero".