Вопрос двоякий: во-первых, это
char c = CHAR_MAX;
c += 1;
оценивается по-другому от
char c = CHAR_MAX;
c = c + 1;
и ответ нет, это не так , потому что C11 / C18 6.5.16.2p3 :
- Составное присваивание формы
E1 op = E2
эквивалентно выражению простого присваивания, E1 = E1 op (E2)
за исключением того, что значение l E1
вычисляется только один раз, а в отношении вызова функции с неопределенной последовательностью операция составного присваивания является единственной оценкой. Если E1
имеет атомарный тип, составное присваивание является операцией чтения-изменения-записи с memory_order_seq_cst
семантикой порядка памяти. 113)
Тогда вопрос в том, что происходит в c = c + 1
. Здесь операнды +
пройти обычные арифметические преобразования, а c
и 1
, следовательно , повышены до int
, если действительно дурацкая архитектура не требует, char
повышена до unsigned int
. Затем вычисляется +
вычисление, и результат типа int
/ unsigned int
преобразуется обратно char
и сохраняется в c
.
Есть 3 способа реализации, в которых это можно оценить:
CHAR_MIN
0 и, следовательно char
, без знака.
Либо char
затем повышен до int
или unsigned int
если он повышен до int
, то CHAR_MAX + 1
обязательно впишется в int
тоже, и не будет переполнения, или если unsigned int
он может соответствовать или обернуть вокруг нуля. Когда полученное значение, которое численно либо CHAR_MAX + 1
или 0
после восстановления по модулю, обратно к c
, после уменьшения по модулю она станет 0, т.е.CHAR_MIN
В противном случае char
подписывается, тогда, если CHAR_MAX
меньше чем INT_MAX
, результат CHAR_MAX + 1
будет соответствовать int
, и стандарт C11 / C18 6.3.1.3p3 применяется к преобразованию, которое происходит после присвоения :
- В противном случае новый тип подписывается, и значение не может быть представлено в нем; либо результат определяется реализацией, либо определяется сигнал реализации.
Или, если sizeof (int) == 1
и char
подписан, то char
повышен до int
, и CHAR_MAX == INT_MAX
=> CHAR_MAX + 1
вызовет переполнение целого числа, и поведение будет неопределенным .
Т.е. возможные результаты:
Если char
это целое число без знака типа, то результат будет всегда 0
, то есть CHAR_MIN
.
В противном случае char
это целочисленный тип со знаком, и поведение определяется / не определяется реализацией:
CHAR_MIN
или некоторое другое значение, определяемое реализацией,
- сигнал реализации определяется, возможно, завершая программу,
- или поведение не определено на некоторых платформах, где
sizeof (char) == sizeof (int)
.
Все операции инкремента c = c + 1
, c += 1
, c++
и ++c
имеют те же побочные эффекты на той же платформе. Оцененное значение выражения c++
будет значением c
до приращения; для остальных трех это будет значение c
после приращения.