Comportamiento intrigante del operador de desplazamiento a la derecha
El operador de desplazamiento a la derecha (>>) exhibe un comportamiento peculiar cuando se trata de valores grandes de desplazamiento a la derecha. Considere el siguiente programa:
#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) El resultado esperado para foo(1, 32) sería 0, pero sorprendentemente devuelve 1. Esto se puede atribuir a lo siguiente:
Desplazamiento lógico versus aritmético Shift
En arquitecturas x86/x86-64, el operador de desplazamiento a la derecha en realidad realiza un desplazamiento lógico a la derecha, lo que significa que llena los bits vacantes con 0, independientemente del signo del operando izquierdo. El comportamiento es similar a usar un >>> b.
Optimización del compilador
En el caso de foo(1, 32), el valor 32 se convierte a int, que efectivamente se trunca a 32 bits. Dado que el valor máximo que puede contener un int es 231-1, el desplazamiento hacia la derecha es esencialmente un >>> (32 % 32), que se evalúa como 0.
Indefinido Comportamiento
El estándar C relevante establece que "el comportamiento no está definido" para desplazamientos a la derecha con un recuento mayor o igual al ancho del operando izquierdo promocionado. En este caso, tanto 1 >> 32 como (int)1 >> (int)32 tienen un recuento mayor que 32, lo que genera resultados impredecibles.
Diferencia con la barra(1, 32)
La barra de funciones toma un entero sin signo de 64 bits, que se garantiza que tendrá un ancho mayor que 32. Por lo tanto, el desplazamiento hacia la derecha en la barra no se ve afectado por un comportamiento indefinido.
Conclusión
El comportamiento del operador de desplazamiento a la derecha se vuelve ambiguo cuando se trata de valores de desplazamiento grandes. En arquitecturas x86/x86-64, se realiza un desplazamiento lógico a la derecha, mientras que en ARM se puede utilizar una implementación diferente. Debido al comportamiento indefinido, el resultado de desplazamientos a la derecha con un recuento mayor o igual al ancho del operando debe evitarse en el código portátil.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3