2012-05-25 8 views
13

estoy leyendo un archivo .cpp que contiene una variable unsigned char, está intentando el bit shift izquierdo 16 bits, ya que unsigned char está compuesto por 8 bits, shift izquierdo 16 bits borrará todos los bits y lo llenará con ocho ceros.qué significa bitwise left shift un char sin signo con 16

unsigned char byte=0xff; byte << 16;

+4

El valor de la expresión no está asignado. –

+2

Tal como está escrito, el compilador optimizará la operación de cambio como no hacer nada. ¿Cuál fue el código real? –

+1

es posible que desee consultar esto: http://stackoverflow.com/questions/437470/type-to-use-to-represent-a-byte-in-ansi-c89-90-c –

Respuesta

16

Cuando se cambia un valor,

unsigned char x = ...; 
int y = x << 16; 

El tipo de x se promueve a int si unsigned char cabe en un int (la mayoría de los sistemas), o para unsigned si unsigned char no cabe en un int (raro). Siempre que su int tenga 25 bits de ancho o más, no se descartará ningún dato .

Tenga en cuenta que esto no tiene ninguna relación con el hecho de que 16 tiene el tipo int.

/* All three are exactly equivalent */ 
x << 16; 
x << 16u; 
x << (unsigned char) 16; 

Fuente: de n1516 (C99 borrador):

§6.5.7 párrafo 3: operadores de desplazamiento a nivel de bit

Las promociones enteros se llevan a cabo en cada uno de los operandos. El tipo de resultado es el del operando izquierdo promocionado.

§6.3.1.1 párrafo 2: booleanos, caracteres y números enteros

Si un int puede representar todos los valores del tipo de original (como restringida por el ancho, para un campo de bits ) , el valor se convierte en un int; de lo contrario, se convierte en un sin signo int. Estas se llaman promociones enteras.

Notas al pie:

: Algunos chips DSP, así como ciertas superordenadores Cray se sabe que tienen sizeof(char) == sizeof(int). Esto simplifica el diseño de la unidad de almacenamiento de carga del procesador a costa de un consumo de memoria adicional.

: Si su desplazamiento a la izquierda es ascendido a int y luego se desborda el int, este es un comportamiento indefinido (demonios pueden volar fuera de la nariz).En comparación, el desbordamiento de un unsigned siempre está bien definido, por lo tanto, los cambios de bit deben realizarse generalmente en en los tipos unsigned.

+0

Muchas gracias por la explicación elaborada. Aunque todavía estoy confundido acerca de la memoria que puede sobrescribir accidentalmente después de promover el 'unsigned char' a' int' – leomayleomay

+1

@leomayleomay: Así no es como funciona. Si asigna un 'int' a una variable' unsigned char', entonces 'int' se convierte. (Esto no es lenguaje ensamblador, después de todo.) –

+0

por lo que el desplazamiento a la izquierda en el bit aquí (16 a la izquierda) hará que la variable en cuestión sea 0, ¿verdad? – leomayleomay

1

Si char encaja dentro int, que será promovido a una int y el resultado será como se espera. Si ese no es el caso, se trata de un comportamiento indefinido de acuerdo con el estándar, y probablemente emitirá una advertencia de compilación. De la norma:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

+1

Nunca causará un comportamiento indefinido si 'char' no cabe en' int', ya que debe encajar dentro de 'unsigned int', y cambia en' unsigned int' nunca están indefinidos. Solo los cambios en los enteros con signo no están definidos, y solo si el resultado matemático no puede ser representado por el tipo. Por ejemplo, '1 << 16 'no está definido si' int 'es 16 bits. –

+1

Las promociones enteras se realizan de hecho, lo que significa que el comportamiento no está definido si 'unsigned char' se promueve a 'int' en lugar de' unsigned int' y el cambio produciría un valor que no se puede representar en un 'int'. – caf

+0

@DietrichEpp: incluso '0 << 16 'es un comportamiento indefinido si' int' es de 16 bits debido a la restricción que se observa en esta respuesta. – caf

Cuestiones relacionadas