omportamiento inesperado del desplazamiento a nivel de bits utilizando gcc

Tengo un programa de prueba como este:

int main()
{
    unsigned n = 32;

    printf("ans << 32 = 0x%X\n", (~0x0U) << 32);
    printf("ans >> 32 = 0x%X\n", (~0x0U) >> 32);

    printf("ans << n(32) = 0x%X\n", (~0x0U) << n);
    printf("ans >> n(32) = 0x%X\n", (~0x0U) >> n);

    return 0;
}  

Produce el siguiente resultado:

ans << 32 = 0x0  ... (1)  
ans >> 32 = 0x0  ... (2)  
ans << n(32) = 0xFFFFFFFF  ... (3)  
ans >> n(32) = 0xFFFFFFFF  ... (4)   

o esperaba que (1) y (3) fueran iguales, así como (2) y (4) iguales.

Utilizando la versión gcc: gcc.real (Ubuntu 4.4.1-4ubuntu9) 4.4.1

¿Qué está pasando

Respuestas a la pregunta(1)

Su respuesta a la pregunta