Причина разных результатов в том, что компилятор (здесь clang 6.0) может выдавать разный код в основной функции и в printBits
.
В main
известно, что number
всегда равно 1 и никогда не меняется. Также «очевидно», что это может дать только один 1
на выходе. Таким образом, оптимизатор переписывает цикл как:
for (char i=64; i > 0; --i)
{
std::cout<< (i == 1 ? 1 : 0);
}
Смотри, мама, без сдвигов!
Сборка выглядит так
012B13CC mov bl,40h ; i = 40h = 64
012B13CE xchg ax,ax ; nop to align the loop
main+30h:
012B13D0 xor eax,eax
012B13D2 cmp bl,1 ; i == 1?
012B13D5 mov ecx,esi
012B13D7 sete al
012B13DA push eax
012B13DB call edi ; edi -> operator<<
012B13DD dec bl
012B13DF jg main+30h (012B13D0h)
В printBits
он не может оптимизировать этот путь, так как функция может быть вызвана из другого места. Таким образом, он выполняет сдвиг (с ошибочным результатом).