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