Это не работает, как ожидалось, потому что вы ожидаете слишком многого.
В случае x86 аппаратное обеспечение не заботится об операциях сдвига, где счетчик больше, чем размер регистра (см., Например, описание инструкции SHL в справочной документации по x86 для объяснения).
Стандарт C ++ не хотел налагать дополнительные затраты, сообщая, что делать в этих случаях, потому что сгенерированный код был бы вынужден добавлять дополнительные проверки и логику для каждого параметрического сдвига.
С этой свободой разработчики компиляторов могут генерировать только одну инструкцию по сборке без какого-либо теста или ветвления.
Более «полезный» и «логический» подход мог бы, например, иметь (x << y)
, эквивалентный (x >> -y)
, а также обрабатывать большие счетчики с логическим и последовательным поведением.
Однако это потребовало бы намного более медленной обработки для сдвига битов, поэтому выбор был делать то, что делает аппаратное обеспечение, оставляя программистам необходимость писать свои собственные функции для дополнительных случаев.
Учитывая, что в этих случаях разные аппаратные средства делают разные вещи, стандарт говорит: «Что бы ни случилось, если вы делаете странные вещи, просто не обвиняйте C ++, это ваша вина», переведенное на юридический язык.