Considérons le code suivant :
bool AllZeroes(const char buf[4])
{
return buf[0] == 0 &&
buf[1] == 0 &&
buf[2] == 0 &&
buf[3] == 0;
}
Assemblage de sortie de Clang 13 avec -O3
:
AllZeroes(char const*): # @AllZeroes(char const*)
cmp byte ptr [rdi], 0
je .LBB0_2
xor eax, eax
ret
.LBB0_2:
cmp byte ptr [rdi + 1], 0
je .LBB0_4
xor eax, eax
ret
.LBB0_4:
cmp byte ptr [rdi + 2], 0
je .LBB0_6
xor eax, eax
ret
.LBB0_6:
cmp byte ptr [rdi + 3], 0
sete al
ret
Chaque octet est comparé individuellement, mais cela aurait pu être optimisé en une seule comparaison d'int 32 bits :
bool AllZeroes(const char buf[4])
{
return *(int*)buf == 0;
}
Résultant en :
AllZeroes2(char const*): # @AllZeroes2(char const*)
cmp dword ptr [rdi], 0
sete al
ret
J'ai également vérifié GCC et MSVC, et aucun d'eux ne fait cette optimisation. Est-ce interdit par la spécification C++ ?
Editer : En changeant le AND court-circuité ( &&
) à ET binaire ( &
) générera le code optimisé. De même, changer l'ordre de comparaison des octets n'affecte pas la génération du code : https://godbolt.org/z/Y7TcG93sP