Мой код:
#include <stdio.h>
#include <limits.h>
int main()
{
char c = CHAR_MAX;
c += 1;
printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}
Вывод:
CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()
Мы видим, что когда мы увеличиваем char
переменную, установленную в CHAR_MAX
, она оборачивается в CHAR_MIN
. Это поведение гарантировано? Или это будет неопределенное поведение или поведение, определяемое реализацией? Что стандарт C99 говорит об этом?
[Примечание: что происходит, когда значение char или C больше, чем CHAR_MAX (127) , преобразуется в -127 в char ? не рассматривает этот вопрос, потому что они говорят о присвоении значения вне диапазона, не увеличивая значение до значения вне диапазона.]
c
char
language-lawyer
standards
integer-overflow
Одинокий ученик
источник
источник
Ответы:
Вопрос двоякий: во-первых, это
оценивается по-другому от
и ответ нет, это не так , потому что C11 / C18 6.5.16.2p3 :
Тогда вопрос в том, что происходит в
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
после приращения.источник
sizeof(int) == 1
потребуетсяCHAR_BITS >= 16
, верно?<pedantic>
ИДК о,CHAR_BITS
ноCHAR_BIT
будет>= 16</pedantic>
.char
всегда должен быть без знака по умолчанию.