Интересно, как C++ ведет себя в этом случае:
char variable = 127;
variable++;
В этом случае переменная теперь равна -128. Однако оператор приращения обернул значение до его нижней границы или произошло переполнение?
Интересно, как C++ ведет себя в этом случае:
char variable = 127;
variable++;
В этом случае переменная теперь равна -128. Однако оператор приращения обернул значение до его нижней границы или произошло переполнение?
Произошло переполнение, что привело к неопределенному поведению.
Раздел 5.5:
Если во время вычисления выражения результат не определен математически или не находится в диапазоне представляемых значений для его типа, поведение не определено [...]
Далее в стандарте отмечается, что целочисленные переполнения в большинстве реализаций игнорируются. Но это не является гарантией.
Обычный char
может быть как подписанным, так и беззнаковым. Если максимальное значение равно 127, то оно должно быть подписано в вашей реализации.
Для беззнаковых типов "переполнение" четко определено и вызывает зацикливание. Для подписанных типов поведение при арифметическом переполнении не определено (обходной цикл типичен, но не обязателен). Но на самом деле это не применимо в данном конкретном случае; вместо этого значение, хранящееся в variable
, определяется реализацией.
Для типов уже, чем int
, все немного сложнее. Этот:
variable ++;
эквивалентно этому:
variable = variable + 1;
К операндам оператора +
применяются «обычные арифметические преобразования», что в данном случае означает, что оба операнда повышаются до int
. Поскольку int
более чем достаточно широк, чтобы вместить результат, переполнения нет; результат 128
и имеет тип int
. Когда этот результат сохраняется обратно в variable
, он преобразуется из int
в char
.
Правила переполнения для преобразований отличаются от правил для арифметических операций, таких как «+». Для преобразования подписанного в подписанное или неподписанного в подписанное, если значение не может быть представлено в целевом типе, поведение не является неопределенным; он просто дает результат, определяемый реализацией.
Для типичной реализации, которая использует представление с дополнением до 2 для целых типов со знаком, сохраненное значение, вероятно, будет -128, но возможны и другие варианты поведения. (Например, реализация может использовать арифметику насыщения.)
Другая (довольно неясная) возможность заключается в том, что char
и int
могут иметь одинаковый размер (что может произойти, только если char
составляет не менее 16 бит). Это может иметь некоторые интересные эффекты, но я не буду вдаваться в подробности (пока).
unsigned char
может быть того же типа, что и char
? То же самое относится и к другим интегральным типам?
- person xtofl; 26.01.2012
char
, signed char
и unsigned char
всегда являются разными типами, но char
имеет то же представление, что и один из них. Точно так же int
и long
— это разные типы, которые могут иметь или не иметь одинаковое представление и так далее.
- person Keith Thompson; 26.01.2012