En C, los valores en la mayoría de las expresiones que son de un tipo más estrecho que int
se promueven a un tipo más amplio antes de que el cálculo tenga lugar. Si int
es lo suficientemente ancho para contener todos los valores del tipo más estrecho, entonces se promueve a int
; de lo contrario, se promociona al unsigned int
.
En este caso, int
es lo suficientemente amplia como para contener todos los valores de su unsigned char
, por lo que sus valores son promovidos a int
.
pktNum
(y por lo tanto, el promocionado pktNum
) puede tener un valor entre 0 y 255 inclusive. Este es el valor que se utilizará en el lado izquierdo del operador !=
.
También puede tener un valor 0 a 255 inclusive. Este valor se promocionará a int
, y luego se negará en bits. El resultado de esta negación a nivel de bits siempre será un número negativo, ya que el bit de signo será negado. Este es el valor que se usará en el lado derecho del operador !=
.
Ningún número negativo puede ser igual al promocionado pktNum
, por lo que la condición siempre es verdadera.
para realizar el cálculo que en realidad se quiere, lo que necesita para enmascarar los más bajos ocho bits después de la negación:
if (pktNum != (~invPktNum & 0xff)) {
return 1;
}
O, alternativamente, puede simplemente negar los bits que le interesan:
if (pktNum != (invPktNum^0xff)) {
return 1;
}
Ah, esto fue todo, y aprendí algo nuevo. ¡Gracias por tu respuesta maravillosamente detallada! – Justin
@ FallSe7en: Bienvenido al mundo maravillosamente confuso de la depuración de C-code. ¡Imagínese tratando de encontrar ese error sin la advertencia del compilador! –