Почему 1-й код не переполняется?
Первый код переполняется точно так же, как второй, и точно в том же месте: присвоение суммыв переменную var1
.
В первом примере начальное значение беззнакового символа var1
, 255, преобразуется в тип int
и к нему добавляется 1.Полученное значение int
256 затем преобразуется в тип unsigned char
, который по определению включает его уменьшение по модулю 256, *, что дает 0. Второй пример точно такой же, за исключением того, что левый операнд ужеint
255, не требующий преобразования.Точно такая же сумма вычисляется, и выполняется точно такое же преобразование в unsigned char
.В одном случае переполнение точно такое же, как и в другом.
Разница заключается лишь в том, что ваш конкретный компилятор считает целесообразным предупредить.Он никоим образом не обязан выдавать какие-либо предупреждения здесь, и он по своему усмотрению выбирает, что вторая версия должна вызывать предупреждение, но первая не должна.
Возможно, он считает, чтовторой относительно вероятнее будет представлять собой программную ошибку, чем первый (правдоподобный), и что соответствующий порог для предупреждения находится между (спорным).Или, возможно, как @RobertHarvey предложил в комментариях, он недостаточно глубоко анализирует код, чтобы признать, что выражение var1 + 1
в этом случае определенно переполняется.
* В целомпреобразование включает в себя уменьшение результата по модулю на единицу больше, чем максимально представимое значение типа результата unsigned char
.У вас есть 8-битные unsigned char
с, что очень нормально.Их диапазон составляет 0 - 255, поэтому уменьшение по модулю 256. Аналогичное относится к преобразованиям для всех других целочисленных типов без знака и к арифметике для типов без знака, где это фактически выполняется.