вызывает ли это неопределенное поведение, если (токен == - 32762) и (ciFirstToken == - 32768)?
token -= ciFirstToken;
НЕТ (длякраткий ответ)
Теперь давайте разберем этот кусочек на части.
1) Согласно expr.ass для составного задания, -=
:
Поведение выражения в форме E1
op = E2
эквивалентно E1 = E1 op E2
за исключением того, что E1
вычисляется только один раз.
выражение:
token -= ciFirstToken;
эквивалентно:
token = token - ciFirstToken;
// ^ binary (not unary)
2) аддитивный оператор (-
) выполняет обычное арифметическое преобразование для операндов арифметического типа.
Согласно expr.arith.conv / 1
Многие бинарные операторы, которые ожидают операнды арифметического или перечислимого типа, вызывают преобразования и выдают типы результатов аналогичным образом.Цель состоит в том, чтобы получить общий тип, который также является типом результата.Этот шаблон называется обычными арифметическими преобразованиями , которые определены следующим образом:
(1.5) В противном случае интегральные преобразования должны выполняться для обоих операндов .
3) Затем оба операнда повышаются до int
.
Согласно conv.prom / 1 :
A prvalue целочисленного типа, отличного от bool
, char16_
t, char32_t
или wchar_t, чей целочисленный коэффициент преобразования меньше, чем ранг int
, можно преобразоватьв prvalue типа int
, если int
может представлять все значения типа источника;
4) После целочисленного продвижения, дальнейшее преобразование не требуется
Согласно expr.arith.conv / 1.5.1
Если оба операнда имеют одинаковый тип, дальнейшее преобразование не выполняетсяНужен.
5) Наконец, Неопределенное поведение для выражений определяется согласно expr.pre :
Яf во время вычисления выражения результат не определен математически или не находится в диапазоне представимых значений для его типа, поведение равно undefined
ЗАКЛЮЧЕНИЕ
Итак, теперь подставляем значения:
token = -32762 - (-32768);
После всех целочисленных повышений оба операнда попадают в допустимый диапазон INT_MIN [1] и INT_MAX [2] .
И после оценки математический результат (6) равензатем неявно преобразуется в short
, что находится в допустимом диапазоне short
.
Таким образом, выражение правильно сформировано .
Большое спасибо @MSalters, @nm и @Arne Vogel за помощь в этом ответе.
Visual Studio 2015 MSVC14 Целочисленные ограничения и MS Целочисленные ограничения определяет:
[1] INT_MIN -2147483648
[2] INT_MAX + 2147483647
SHRT_MIN –32768
SHRT_MAX + 32767