В C значения в большинстве выражений, которые имеют тип, более узкий, чем int
, переводятся в более широкий тип до выполнения вычисления. Если int
достаточно широк, чтобы вместить все значения более узкого типа, то оно повышается до int
; в противном случае он повышается до unsigned int
.
В этом случае int
достаточно широк, чтобы вместить все значения вашего unsigned char
, поэтому ваши значения повышаются до int
.
pktNum
(и, следовательно, повышенный pktNum
) может иметь значение от 0 до 255 включительно. Это значение, которое будет использоваться в левой части оператора !=
.
invPktNum
также может иметь значение от 0 до 255 включительно. Это значение будет повышено до int
, а затем будет поразрядно отрицаться. Результатом этого побитового отрицания всегда будет отрицательное число, поскольку знаковый бит будет отрицаться. Это значение, которое будет использоваться в правой части оператора !=
.
Никакое отрицательное число не может быть равным повышенному pktNum
, поэтому условие всегда выполняется.
Чтобы выполнить вычисление, которое вы на самом деле хотите, вам нужно замаскировать младшие восемь бит после отрицания:
if (pktNum != (~invPktNum & 0xff)) {
return 1;
}
Или же вы можете просто отменить интересующие вас биты:
if (pktNum != (invPktNum ^ 0xff)) {
return 1;
}