Поведение оператора приращения на границах для символьного типа - PullRequest
2 голосов
/ 26 января 2012

Интересно, как C ++ ведет себя в этом случае:

char variable = 127;
variable++;

В этом случае переменная теперь равна -128. Однако оператор приращения перенес значение в нижнюю границу или произошло переполнение?

Ответы [ 2 ]

6 голосов
/ 26 января 2012

Произошло переполнение, что привело к неопределенному поведению .

Раздел 5.5:

Если во время вычисления выражения результат не определен математически или вне диапазона представимых значений для его типа , поведение не определено [...]

В стандарте отмечается, что целочисленные переполнения в большинстве реализацийигнорируются.Но это не гарантия.

3 голосов
/ 26 января 2012

Обычный char может быть подписанным или без знака. Если максимальное значение равно 127, оно должно быть подписано в вашей реализации.

Для неподписанных типов «переполнение» четко определено и вызывает перенос. Для типов со знаком поведение по арифметическому переполнению не определено (перенос типичен, но не обязателен). Но это на самом деле не применимо в данном конкретном случае; вместо этого значение, хранящееся в variable, определяется реализацией.

Для типов, более узких, чем int, все немного сложнее. Это:

variable ++;

эквивалентно этому:

variable = variable + 1;

Операнды оператора + применяют к ним "обычные арифметические преобразования", что в данном случае означает, что оба операнда переводятся в int. Поскольку int достаточно широка, чтобы вместить результат, переполнения нет; результат 128 и имеет тип int. Когда этот результат сохраняется в variable, он преобразуется из int в char.

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

Для типичной реализации, которая использует представление с добавлением 2 для целочисленных типов со знаком, сохраненное значение, вероятно, будет -128, но возможны другие варианты поведения. (Например, реализация может использовать насыщающую арифметику.)

Еще одна (довольно неясная) возможность состоит в том, что char и int могут иметь одинаковый размер (что может произойти, только если char равно как минимум 16 битам). Это может иметь некоторые интересные эффекты, но я не буду вдаваться в это (пока).

...