Почему операция с переменной не переполняется в C - PullRequest
0 голосов
/ 29 января 2019

У меня есть код, похожий на этот в C:

int main(){
   unsigned char var1;

   var1 = 255;
   var1 = var1 + 1;

   printf("The result is = %i", var1);

}

Я думаю, что он переполнится, так как максимальный тип для var1 равен 255, поэтому, когда вы увеличиваете его до 1, он будет 256но результат равен 0.

Но когда я изменил код примерно так:

int main(){
   unsigned char var1;

   var1 = 255+ 1;

   printf("The result is = %i", var1);

}

В результате выдается ошибка переполнения, например «предупреждение: преобразование без знака из int в беззнаковое»char 'изменяет значение с' 256 'на' 0 '[-Woverflow] ".

Почему первый код не переполняется?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Почему 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. Аналогичное относится к преобразованиям для всех других целочисленных типов без знака и к арифметике для типов без знака, где это фактически выполняется.

0 голосов
/ 29 января 2019

Обтекание для беззнакового символа (по существу, байта) является заданным.

Ваш второй пример, однако, добавляет два целых числа.Преобразование из 256 в int в ноль в байте означает потерю информации;отсюда и предупреждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...