Comportement intrigant de l'opérateur de décalage vers la droite
L'opérateur de décalage vers la droite (>>) présente un comportement particulier lorsqu'il traite de grandes valeurs de décalage à droite . Considérons le programme suivant :
<code class="c++">#include <iostream> #include <stdint.h> int foo(int a, int b) { return a >> b; } int bar(uint64_t a, int b) { return a >> b; } int main() { std::cout << "foo(1, 32): " << foo(1, 32) << std::endl; std::cout << "bar(1, 32): " << bar(1, 32) << std::endl; std::cout << "1 >> 32: " << (1 >> 32) << std::endl; //warning std::cout << "(int)1 >> (int)32: " << ((int)1 >> (int)32) << std::endl; //warning }
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 vs décalage arithmétique
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 le vide bits à 0, quel que soit le signe de l’opérande de gauche. Le comportement est similaire à l'utilisation d'un >>> b.
Optimisation du compilateur
Dans le cas de foo(1, 32), la valeur 32 est convertie en int, qui est effectivement tronquée à 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.
Comportement non défini
La norme C pertinente indique que "le comportement est indéfini" pour les changements de vitesse avec un nombre supérieur supérieure ou égale à la largeur de l’opérande gauche promu. Dans ce cas, les deux 1 >> 32 et (int)1 >> (int)32 ont 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 format 64 bits entier non signé, dont la largeur est garantie supérieure à 32. Par conséquent, le décalage vers la droite en 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.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!