Как уже упоминалось другими, согласно стандарту C поведение сдвига не определено.
Тем не менее, программа печатает 1. Низкоуровневое объяснение того, почему она печатает 1, выглядит следующим образом:
При компиляции без оптимизации компилятор (GCC, clang) выдает инструкцию SHL
:
...
mov $32,%ecx
shll %cl,0x1c(%esp)
...
Документация Intel для SHL
инструкции гласит:
SAL / SAR / SHL / SHR-Shift
Счет маскируется до 5 бит (или 6 бит, если в 64-битном режиме используется REX.W). Диапазон счетчиков ограничен от 0 до 31 (или 63, если используется 64-битный режим и REX.W).
Маскирование счетчика сдвига 32 (двоичный код 00100000) до 5 битов дает 0 (двоичный код 00000000). Поэтому инструкция shll %cl,0x1c(%esp)
не выполняет никакого смещения и оставляет значение i
без изменений.