2010-08-14 7 views
23

Normalmente, C requiere que los operandos de un operador binario se promuevan al tipo del operando de mayor rango. Esto puede ser explotado para evitar llenar código con moldes detallados, por ejemplo:Bitshift y la promoción de enteros?

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

etc.

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

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

yo esperaría que el tipo del operando de la derecha para hacer que el operando de la izquierda para ser promovidos al unsigned long long para que el cambio tenga éxito. Pero en cambio, impresiones de gcc una advertencia:

warning: left shift count >= width of type 

es GCC roto, o es el estándar de hacer alguna excepción a las reglas de la promoción Tipo de bitshifts?

+0

¿Promocionará de todos modos, independientemente de la advertencia? (es solo una advertencia, después de todo). –

+1

¿No podría simplemente usar una macro corta para producir el reparto detallado? Me gusta '#define ULL (x) ((unsigned long long) x)'? – Borealid

+1

@Robert: No, produce un no-op, como si hubiera escrito '' 32 'simple. @Borealid: Sí, podría, pero me gusta escribir código que pueda copiarse y pegarse en cualquier lugar (por ejemplo, otros proyectos) sin necesidad de definir/encabezados adicionales. Odio cosas como 'typedef unsigned int uint;'. –

Respuesta

23

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 desplazamiento de bit, & &, ||, operador de coma y operadores de asignación. Esta es la regla para los operadores de desplazamiento de bits:

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.

+1

Gracias, esto es lo que estaba buscando. –

0

El problema es que la promoción solo funciona según lo que su 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).

Cuestiones relacionadas