Является ли сдвиг знакового бита подписанным коротким неопределенным поведением в C?

Я слышал, что переход на бит целого числа со знаком, т.е.

int test = INT_MAX;
test = (test<<1) + 1;

является неопределенным поведением из-за того, что test больше, чем INT_MAX. Но будет ли такое поведение встречаться в коротких переменных со знаком, т.е.

short test1 = SHRT_MAX;
test1 = (test1<<1) + 1;

?

На данный момент я не сталкивался с какой-либо соответствующей документацией.

РЕДАКТИРОВАТЬ: я знаю, что поведение undefined приведет к целым числам, но не к коротким.


person Benedict Aaron Tjandra    schedule 12.12.2018    source источник
comment
@Sander Я бы не назвал это дубликатом, потому что shorts будут повышены до ints перед сдвигом, что добавляет здесь дополнительную сложность.   -  person interjay    schedule 12.12.2018
comment
@interjay: достаточно честно - близкое голосование отозвано   -  person Sander De Dycker    schedule 12.12.2018
comment
Проблема заключается в том, что оператор сдвига C является 'логическим сдвигом', а это означает, что он не заботится об обработке знаков. Преобразование между целыми числами следует хорошо известным правилам, которые в конкретном случае, когда MAX_INT >= MAX_SHORT всегда должно быть истинным, должны гарантировать правильное представление short в int. Но когда дело доходит до сдвига, поведение зависит от машины и конкретных инструкций, закодированных компилятором. т.е. отрицательное число может стать положительным при сдвиге вправо и наоборот при сдвиге влево. Но что, если ЦП вместо этого использует арифметические сдвиги SAR/SAL?   -  person Frankie_C    schedule 12.12.2018


Ответы (1)


Когда в большинстве типов выражений используется небольшой целочисленный тип, он продвигается до int ( если int может соответствовать всем значениям исходного типа), и затем выражение выполняется для int.

Это дает две возможности:

  1. На платформе, где int имеет тот же размер, что и short, смещение будет иметь неопределенное поведение, поскольку оно смещается в бит знака int. (Точнее причина в том, что результат не может быть представлен как int). См. C11 6.5.7p4.
  2. На платформе, где int имеет больше битов, чем short, сам сдвиг будет успешным (хотя он может быть неопределенным, если вы выполняете сдвиг более чем на 1). Однако, когда вы присваиваете результат обратно переменной short, значение не сможет быть представлено как short. Фактическое значение, которое будет присвоено, определяется реализацией. См. C11 6.3.1.3p3.
person interjay    schedule 12.12.2018