Hi Juan,
Juan Lang wrote:
The case I objected to is a curious one. I had a look at K&R's type promotion rules (2nd edition, section A6.5) and I'm confused what the compiler is doing here. The if-block is:
if (pbEncoded[1] + 1 > cbEncoded)
Rewriting the parenthesized expression as types rather than variables/values yields:
unsigned char + int > unsigned int
According to K&R, the unsigned char should get promoted to unsigned int (I think), hence:
unsigned int + int > unsigned int
Actually, I think it is true to say that "integral promotion" is first applied to each operand of the addition, giving:
int + int > unsigned int
since an int is large enough to hold all possible values of an unsigned char. So the warning is correct, since, in the general case, bad things would happen if the left-hand sum were to produce a negative value.
When an unsigned type and a signed type are together in an expression, the signed type is promoted to unsigned:
unsigned int + unsigned int > unsigned int
True, unless the signed operand has more bits than the unsigned one (e.g. on a system with 32-bit intS and 64-bit longS). The "usual arithmetic conversions" are rather complicated, but, in our example, the int sum will get promoted to an unsigned int. So here
int > unsigned int
becomes
unsigned int > unsigned int
An example of where this could go wrong is where the comparison (-1 > 0) [should be false] might be evaluated as (UINT_MAX > 0) [always true].
The promotion of unsigned char to signed/unsigned int is platform-dependent, so perhaps gcc's analysis assumes it's signed? In any case, by my reading the gcc warning is simply wrong. I could be wrong of course.
Integral promotion dictates that an anything whose type is of lower rank than an int will be promoted to an int if that is big enough to hold all possible values of the original type, else it will be promoted to an unsigned int. So an unsigned char (always eight bits wide) will always promote to an int (always >= sixteen bits wide). But the promotion of unsigned short to signed/unsigned int will depend on the relative widths involved, so will be platform dependent, as will the usual arithmetic conversion of int to signed/unsigned long.
(I hope I managed to get all of that right.)
Anyway, good luck with your warning-crushing war ;-) --Juan
Thank you and keep up the good work, too!