Echa un vistazo al ejemplo:
unsigned char c = 64; /* 0100 0000 */ c = (c << 2 && 512); /* 512: 10 0000 0000 */ Si cambio c dos veces a la izquierda, debería pasar de 0100 0000 (64) a este 0001 0000 0000 (256). Entonces mi char c de 8 bits solo tiene ceros. Al final, me pregunto por qué la expresión (c << 2 && 512) es verdadera (1) y no falsa (0), porque mi c solo tiene ceros.
Desde el Estándar C (6.5.7 Operadores de desplazamiento bit a bit)
3 Las promociones de enteros se realizan en cada uno de los operandos. El tipo del resultado es el del operando izquierdo promocionado.
Entonces en esta expresión
c << 2 el objeto c se promociona al tipo int y el resultado también tiene el tipo int .
Como los dos operandos del operador lógico AND no son iguales a 0 , la expresión completa se evalúa como 1 .
Del estándar C (6.5.13 Operador lógico AND)
3 El operador && dará como resultado 1 si sus dos operandos se comparan como distintos a 0; de lo contrario, arroja 0. El resultado es de tipo int.
Parece que está confundiendo el operador lógico AND && con el operador bit a bit AND & .
si vas a escribir
c = (c << 2 & 512); entonces la variable c tendrá el valor 0.
& es un AND bit a bit. Cada bit en sus resultados es el AND de los dos bits correspondientes en su entrada. El AND bit a bit de 01 0000 0000 2 y 10 0000 0000 2 sería 00 0000 0000 2 .
&& es un Y lógico. Su resultado es 1 si sus dos operandos son distintos de cero y 0 en caso contrario. El AND lógico de 01 0000 0000 2 y 10 0000 0000 2 es 1.
La respuesta de Vlad es la explicación.
Aquí hay una visualización de lo difícil que es convertir algo en un tipo de datos especial, en presencia de promoción:
#include <stdio.h> int main() { printf("Hello, World!\n"); unsigned char c = 64; if (c << 2 ) {printf("Yes 1.\n");} if (c << '\2') {printf("Yes 2.\n");} if ((unsigned char)(c << 2)) {printf("Yes 3.\n");} else {printf(" No 3.\n");} if ((unsigned char)(c) << (unsigned char)(2)) {printf("Yes 4.\n");} else {printf(" No 4.\n");} return 0; }Salida (por ejemplo, aquí https://www.tutorialspoint.com/compile_c_online.php ):
Hello, World! Yes 1. Yes 2. No 3. Yes 4. La versión de su código falla en 1.
Una versión que intenta usar operandos char sin firmar falla en 2.
Solo 3, un reparto explícito tras la operación logra anular la promoción.
Mientras que 4, intentar usar una conversión explícita en los operandos antes de que la operación vuelva a fallar.