Bitshift y la promoción de enteros?

Normalmente, C requiere que los operandos de un operador binario se promuevan al tipo del operando de mayor rango. Esto se puede aprovechar para evitar llenar el código con moldes detallados, por ejemplo:

if (x-48U<10) ... y = x+0ULL << 40; 

etc.

Sin embargo, he descubierto que, al menos con gcc, este comportamiento no funciona para bitshifts. Es decir

 int x = 1; unsigned long long y = x << 32ULL; 

Esperaría que el tipo del operando de la derecha haga que el operando de la izquierda se promueva a unsigned long long para que el cambio tenga éxito. Pero en cambio, gcc imprime una advertencia:

 warning: left shift count >= width of type 

¿Está roto el gcc, o el estándar hace alguna excepción a las reglas de promoción de tipo para los cambios de bits?

Las llamadas conversiones aritméticas habituales se aplican a muchos operadores binarios, pero no a todos. Por ejemplo, no se aplican a los operadores de cambio de bit, &&, ||, operador de coma y operadores de asignación. Esta es la regla para los operadores de cambio de bit:

6.5.7 … 3 Semántica …
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.

El problema es que la promoción solo funciona según lo que tu plataforma defina como int . Como algunas otras respuestas han indicado, el operador de desplazamiento de bit promoverá el operando izquierdo a un int. Sin embargo, aquí un int se define como un valor de 32 bits. La conversión entera no se promocionará a long long (64 bits).