Что произойдет, если мы побитово сдвинем целое число больше, чем его размер

При компиляции Visual Studio следующего кода C результат равен 4 .

void main() { int c = 1; c = c<<34;}

Код сборки, как видно из окна дизассемблирования Visual Studio,

shl eax,22h

Из ассемблера легко увидеть, что мы сдвигаем 34. Поскольку целое число здесь равно 4 байтам, из результатов очевидно, что операция по модулю выполнялась на машинном уровне, чтобы это работало как сдвиг на 2.

Мне было интересно, стандартизировано ли это поведение для разных платформ или варьируется в зависимости от платформы?


person Manik Mahajan    schedule 20.04.2013    source источник
comment
Что, если мы объявим main как void main() {...}?   -  person wildplasser    schedule 20.04.2013
comment
под какой архитектурой вы запускаете программу? i386 ?   -  person Lefteris E    schedule 20.04.2013
comment
это x86-64, но моя Windows 32-битная.   -  person Manik Mahajan    schedule 20.04.2013
comment
@wildplasser с этими точками выдаст ошибку компиляции   -  person Manik Mahajan    schedule 20.04.2013


Ответы (2)


Происходит неопределенное поведение. Это стандартизировано стандартом языка (см. раздел 6.5.7 Bitwise shift operators стандарта C от 1999 г.). Однако наблюдаемые эффекты УБ не стандартизированы и могут варьироваться.

Что касается shl eax, 22h, счетчик сдвига будет усечен ЦП до 5 бит (см. документацию), и эта инструкция действительно будет вести себя как shl eax, 2.

person Alexey Frunze    schedule 20.04.2013
comment
Где это сказано про усечение? download.intel.com/products/processor/manual/325462.pdf - person Lefteris E; 20.04.2013
comment
@LefterisE Тут же, в Vol. 2B, раздел SAL/SAR/SHL/SHR—Shift: The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). Где ты это искал и зачем? - person Alexey Frunze; 20.04.2013
comment
Я хотел подтвердить то, что вы сказали, чтобы проголосовать за ваш ответ - person Lefteris E; 21.04.2013

Согласно этой статье на MSDN:

Результат не определен, если правый операнд выражения сдвига отрицателен или если правый операнд больше или равен количеству битов в (повышенном) левом операнде. Никакая операция сдвига не выполняется, если правый операнд равен нулю (0).

person Jonathan Wood    schedule 20.04.2013