В языке C в выражениях часто происходят преобразования типов (type promotion, type conversion), регулируемые стандартом:
char, short) автоматически преобразуются к int или unsigned int перед арифметическими операциями.Пример:
unsigned short a = 65535; signed short b = -1; printf("%d ", a + b); // зависит от преобразования!
Рекомендация: внимательно следите за типами операндов, особенно при работе с битовыми операциями, длинами массивов, индексами, и избегайте неявного смешивания знаковых и беззнаковых типов.
Что выведет следующий фрагмент?
unsigned int u = 1; int i = -2; printf("%d ", u + i);
Ответ: Переменная i будет преобразована к unsigned int, итоговое значение станет очень большим, т.к. результат под капотом: 1U + (unsigned int)-2U, что даст число, близкое к UINT_MAX (4294967295). Будет напечатано отрицательное число только если printf форматировать как int, иначе мусор.
История
В вычислении средних значений интенсивности изображения перепутали
intиunsigned int. Отрицательные значения неверно транслировались через unsigned и давали гигантские числа, приводя к переполнению буфера изображения.
История
Во встроенной прошивке считали длину строки через
size_t, а индексировали массив черезint. На проверке условия выхода за пределы массива сравнивалиint i >= size_t len, что ломало логику для длинных строк и вызывало баги при сравнении разных типов (size_t — unsigned).
История
Разработчик на финансовом проекте вычислял остаток деления для отрицательных чисел через
%, забывая, что знак результата для отрицательных операндов зависит от реализации. В одном окружении результат был положительный, в другом — отрицательный, отчего расчёты периодически "съезжали".