Comportement intrigant de l'opérateur de décalage à droite
L'opérateur de décalage à droite (>>) présente un comportement particulier lorsqu'il traite de grandes valeurs de décalage à droite. Considérez le programme suivant :
#include
#include
int foo(int a, int b)
{
return a >> b;
}
int bar(uint64_t a, int b)
{
return a >> b;
}
int main()
{
std::cout > 32: " > 32) > (int)32: " > (int)32) Le résultat attendu pour foo(1, 32) serait 0, mais étonnamment, il renvoie 1. Cela peut être attribué aux éléments suivants :
Décalage logique par rapport à l'arithmétique Shift
Sur les architectures x86/x86-64, l'opérateur de décalage vers la droite effectue en fait un décalage logique vers la droite, ce qui signifie qu'il remplit les bits libérés avec 0, quel que soit le signe de l'opérande de gauche. Le comportement est similaire à l'utilisation de a >>> b.
Optimisation du compilateur
Dans le cas de foo(1, 32), la valeur 32 est convertie en int, qui est effectivement tronqué à 32 bits. Puisque la valeur maximale qu'un int peut contenir est 231-1, le décalage vers la droite est essentiellement un >>> (32 % 32), qui est évalué à 0.
Non défini Comportement
La norme C pertinente indique que "le comportement n'est pas défini" pour les décalages vers la droite avec un nombre supérieur ou égal à la largeur de l'opérande gauche promu. Dans ce cas, 1 >> 32 et (int)1 >> (int)32 ont tous deux un nombre supérieur à 32, ce qui conduit à des résultats imprévisibles.
Différence avec bar(1, 32)
La barre de fonctions prend un entier non signé de 64 bits, dont la largeur est garantie supérieure à 32. Par conséquent, le décalage vers la droite dans la barre n'est pas affecté par un comportement non défini.
Conclusion
Le comportement de l'opérateur de décalage à droite devient ambigu lorsqu'il s'agit de valeurs de décalage élevées. Sur les architectures x86/x86-64, un décalage logique vers la droite est effectué, tandis que sur ARM, une implémentation différente peut être utilisée. En raison d'un comportement non défini, le résultat de décalages vers la droite avec un nombre supérieur ou égal à la largeur de l'opérande doit être évité dans le code portable.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3