Because the standard says so. The operands for binary operators go through a whole campaign in which everything less than int raised to int ; the results of the type int operation. And if the original value was, say, 0x12 , the results will be 0x120 and assigning it an unsigned char will cause the value to change. (The assigned value will be 0x20 .) From where the warning appears.
EDIT:
From the standard (Β§5.8 Shift operators): βThe operands must have an integral or non-listed type of listing and integral promotions. The type of result is the result of an advanced left operand.β Unlike other binary operators, there is no effort to find a common type from two operators: The result type is the left operand, period. But integral promotion is still happening: unsigned char will be up to int (or up to unsigned int if int has size 1).
source share