Целочисленное переполнение – почему бы и нет [дубликат]

StackOverflow https://stackoverflow.com/questions/6025087

Вопрос

Возможный дубликат:
Добавление двух символов дает int

Учитывая следующий код C++:

unsigned char a = 200;
unsigned char b = 100;

unsigned char c = (a + b) / 2;

Выход 150 как логически ожидается, однако в выражении не должно быть целочисленного переполнения (a + b)?

Очевидно, что здесь должно быть целочисленное продвижение, чтобы справиться с переполнением, иначе происходит что-то еще, чего я не вижу.Мне было интересно, может ли кто-нибудь просветить меня, чтобы я мог знать, на что я могу и не должен полагаться с точки зрения целочисленного продвижения и переполнения.

Это было полезно?

Решение

Ни C++, ни C не выполняют арифметические вычисления с «меньшими» целочисленными типами, например: char и short.Эти типы почти всегда получают повышение до int прежде чем начнутся дальнейшие вычисления.Итак, ваше выражение действительно оценивается как

unsigned char c = ((int) a + (int) b) / 2;

P.S.На какой-то экзотической платформе, где диапазон int не охватывает диапазон unsigned char, тип unsigned int будет использоваться в качестве целевого типа для продвижения.

Другие советы

Нет, это не ошибка.

Компилятор всегда выполняет вычисления с минимальной целочисленной точностью, результат будет преобразован обратно в беззнаковый символ только при присваивании.

Это в стандарте.

Согласно другим ответам, это не ошибка на x86 и других (вменяемых) 32-битных и 16-битных архитектурах.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top