Whenever you have a binary operator (one of + - * / % << >> & | ^ == != <= >= ) Between two integer operands of different types, two types are converted to a common type before execution operations. Rules for deciding on a converted type (from section 6.3.1.8 of the C99 standard):
If both operands are of the same type, then further conversions are not required.
Otherwise, if both operands are of integer types or both have unsigned integer types, the operand with the type of a lower integer conversion rank is converted to the operand type with a higher rank.
Otherwise, if the operand with an unsigned integer type has a rank greater than or equal to the ranks of the type of another operand, then the operand with an integer type with a sign is converted to the type of the unsigned operand of an integer type.
Otherwise, if the type of the operand with a signed integer type can represent all values โโof the type of the operand with an unsigned integer type, then the operand with an unsigned integer is converted to the operand type with a signed integer type.
Otherwise, both operands are converted to an unsigned integer type corresponding to the type of the operand with a signed integer type.
In this case, char can be either an integer type with a signature, or unsigned - its signature is determined by the implementation. Fortunately, int can represent all possible values โโof a char , regardless of whether char signed or not, if you are on a system where char is 8 bits and int is at least 16 bits.
If the char sign is signed, then the second paragraph above is applied, so both operands are converted to int (type with a higher rank, the rank is determined in a somewhat complicated way, but is essentially equivalent to the size of the type bit). Since 0x98, like a signed char , is negative, it converts to the integer -104, which is then less than 7.
If there is no character instead of char , then the fourth paragraph is used instead. An unsigned char will be converted to 152 as an int , which is greater than 7.
Never rely on char signed or unsigned. If you need 8-bit integers with a specific signature, I explicitly use signed char or unsigned char or use the C99 types int8_t and uint8_t defined by int <stdint.h> .
It is very easy to bite subtle mistakes caused by whole promotion rules. I highly recommend that you always compile with -Wall with gcc, which will warn you about comparing unsigned integers that are often the cause of errors.