Целочисленное переполнение - почему
Возможный дубликат:
Добавление двух символов создает int
Учитывая следующий код С++:
unsigned char a = 200;
unsigned char b = 100;
unsigned char c = (a + b) / 2;
Результат равен 150, поскольку логически ожидалось, однако не должно быть целочисленного переполнения в выражении (a + b)
?
Очевидно, что здесь должно быть целочисленное продвижение, чтобы справиться с переполнением, или что-то еще происходит, что я не вижу. Мне было интересно, может ли кто-нибудь просветить меня, поэтому я могу знать, что я могу, и не должен полагаться на целую рекламу и переполнение.
Ответы
Ответ 1
Ни С++, ни C не выполняют арифметические вычисления с "меньшими" целыми типами, такими как char
и short
. Эти типы почти всегда повышаются до int
до начала любых дальнейших вычислений. Итак, ваше выражение действительно оценивается как
unsigned char c = ((int) a + (int) b) / 2;
P.S. На некоторой экзотической платформе, где диапазон int
не охватывает диапазон unsigned char
, тип unsigned int
будет использоваться в качестве целевого типа для продвижения по службе.
Ответ 2
Нет, это не ошибка.
Компилятор всегда вычисляет минимум минимальной точности, результат будет преобразован обратно в unsigned char только при назначении.
Это стандарт.
Ответ 3
В других ответах это не ошибка на x86 и других (нормальных) 32-битных и 16-битных архитектурах.
Однако, на более мелких или менее правильных архитектурах (как правило, очень малых микроконтроллерах) такие вещи, вероятно, начнут вызывать проблемы, особенно если кто-то, кто реализовал ваш компилятор, не имеет бюджета на тестирование/проверку некоторых из более крупных компаний (опять же, микроконтроллеры).