Salida inesperada al ejecutar el desplazamiento a la izquierda por 32 bits

Cuando hago un desplazamiento a la izquierda de un hexágono, obtengo -1 como salida con el siguiente código:

unsigned int i,j=0; i= (0xffffffff << (32-j)); printf("%d",i); 

De manera similar, cuando cambié el valor de cambio a 32, la salida es 0, pero recibo advertencias del comstackdor como (left shift count >= width of type)

 unsigned int i,j=32; i= (0xffffffff << (32)); printf("%d",i); 

Esperaba los mismos resultados en ambos casos (es decir, 0), pero me confundí porque el resultado es incorrecto en el caso # 1, y en el caso # 2 el resultado es correcto, ¡pero el comstackdor advierte!

El resultado es el mismo en máquinas x86 de 32 y 64 bits.

¿Alguien puede explicar los resultados anteriores?

Es un comportamiento indefinido a la mierda a la izquierda 32 o superior en un entero de 32 bits. De eso se trata el error.

C11 6.5.7 Operadores de cambio bit a bit

Las promociones enteras se realizan en cada uno de los operandos. El tipo de resultado es el del operando izquierdo promovido. Si el valor del operando derecho es negativo o es mayor o igual que el ancho del operando izquierdo promovido, el comportamiento no está definido.

Cambiar una variable de 32 bits por 32 produce un comportamiento indefinido.

Aquí está el ensamblado generado por el comstackdor VS-2013:

  int n = 0; mov dword ptr [n],0 int a = 0xFFFFFFFF << 32; mov dword ptr [a],0 int b = 0xFFFFFFFF << (32-n); mov ecx,20h sub ecx,dword ptr [n] or eax,0FFFFFFFFh shl eax,cl mov dword ptr [b],eax 

Como puedes ver, lo que sucede de facto es:

  • Cuando cambias por un valor constante de 32, el comstackdor simplemente establece el resultado en 0
  • Cuando se desplaza por una variable (como 32-n con n==0 ), el comstackdor usa shl

El resultado real de shl depende de la implementación de esta operación en la architecture subyacente. En su procesador, es probable que tome el segundo operando módulo 32, por lo tanto, el primer operando se desplaza en 0.

Una vez más, la descripción anterior no está dictada por el estándar, por lo que realmente depende del comstackdor en uso.