Целочисленное переполнение - почему

Возможный дубликат:
Добавление двух символов создает 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-битных архитектурах.

Однако, на более мелких или менее правильных архитектурах (как правило, очень малых микроконтроллерах) такие вещи, вероятно, начнут вызывать проблемы, особенно если кто-то, кто реализовал ваш компилятор, не имеет бюджета на тестирование/проверку некоторых из более крупных компаний (опять же, микроконтроллеры).