Введение
Следует рассмотреть два практических случая:
char
без знака и восемь битов.Для этого результат равен 2. char
со знаком и восемью битами.Для этого результат определяется реализацией или повышается сигнал, определяемый реализацией.
Тип символа без знака и восемь битов
В этом случае char c = 250;
является простым;он инициализирует c
до 250. Затем в c += 8;
оператор эквивалентен c = c + 8;
.В этом операторе c
повышается до int
, и добавление выполняется, в результате чего получается 258. Наконец, этот результат должен быть преобразован в char
для сохранения в c
.
.Правило для преобразования в тип без знака состоит в том, чтобы корректировать значение по модулю «на единицу больше максимального значения», которое может быть представлено.То есть для беззнакового char
, где максимальное значение равно 255, мы добавляем или вычитаем 256, чтобы сделать представимое значение.Таким образом, 258 становится 258−256 = 2, а c
устанавливается на 2.
Тип символа подписан и восемь битов
В этом случае char c = 250;
пытается инициализировать c
со значением, которое он не может представлять.Согласно C 2018 6.7.9 11, инициализация выполняется как назначение.Согласно 6.5.16.1 2, присваивание преобразует значение в тип левого операнда (после преобразования в lvalue).В соответствии с 6.3.1.3 3 преобразование значения, которое не может быть представлено в подписанный тип, определяется реализацией:
В противном случае новый тип подписывается и значение не может быть представлено в нем;либо результат определяется реализацией, либо генерируется определяемый реализацией сигнал.
Если выполнение продолжается после char c = 250;
до c += 8;
, то 8 добавляется к любому значению c
, инициализированному для,Это не может быть переполнено, так как операнды повышаются до типа int
, и любое значение char
плюс 8 представимо в int
.Если результат сложения представлен в char
, он сохраняется в c
.В противном случае правила преобразования применяются снова: результат определяется реализацией или генерируется сигнал, определяемый реализацией.
Гипотетические ситуации
Эти ситуации редко или никогда не встречаются в современной практике.
Если char
подписано и девять битов, то 250 представимо, поэтому c
инициализируется равным 250. Затем, в c += 8;
, сложение дает результат, который не представлен в char
(максимум будет 255), поэтому применяются правила преобразования, описанные выше, и результат определяется реализацией или повышается результат реализации.
Если char
шире, чем девять бит, ошибок не возникает,и c
заканчивается 258.
Если char
была такой же ширины, как int
(гипотетическая возможность обсуждалась в другом месте по переполнению стека), и char c = 250;
были изменены, скажем, на char c = INT_MAX-5;
, тогда c
будет инициализирован без проблем, но c += 8;
переполнится во время арифметики, и тогда поведение не определено стандартом Cе.