W języku C w wyrażeniach często zachodzą konwersje typów (type promotion, type conversion), regulowane standardem:
char, short) automatycznie konwertowane są na int lub unsigned int przed operacjami arytmetycznymi.Przykład:
unsigned short a = 65535; signed short b = -1; printf("%d ", a + b); // zależy od konwersji!
Zalecenie: uważnie obserwuj typy operandów, szczególnie przy pracy z operacjami bitowymi, długościami tablic, indeksami i unikaj niejawnego mieszania typów signed i unsigned.
Co wyświetli poniższy fragment?
unsigned int u = 1; int i = -2; printf("%d ", u + i);
Odpowiedź: Zmienna i zostanie skonwertowana na unsigned int, a końcowa wartość stanie się bardzo duża, ponieważ wynik pod maską: 1U + (unsigned int)-2U, co da liczbę bliską UINT_MAX (4294967295). Zostanie wydrukowana liczba ujemna tylko jeśli printf będzie formatować jako int, w przeciwnym razie śmieci.
Historia
Podczas obliczania średnich wartości intensywności obrazu pomylono
intzunsigned int. Ujemne wartości błędnie konwertowane przez unsigned dawały ogromne liczby, prowadząc do przepełnienia bufora obrazu.
Historia
W wbudowanym oprogramowaniu obliczano długość łańcucha jako
size_t, a indeksowano tablicę przezint. Przy sprawdzaniu warunku przekroczenia granic tablicy porównywanoint i >= size_t len, co łamało logikę dla długich łańcuchów i powodowało błędy podczas porównania różnych typów (size_t — unsigned).
Historia
Programista przy projekcie finansowym obliczał resztę z dzielenia dla liczb ujemnych przez
%, zapominając, że znak wyniku dla ujemnych operandów zależy od implementacji. W jednym środowisku wynik był dodatni, w innym – ujemny, co powodowało okresowe "zakłócenia" obliczeń.