In am working on something and came across code similar to the following:
#define MODULUS(a,b) ((a) >= 0 ? (a)%(b) : (b)-(-a)%(b))
unsigned char w;
unsigned char x;
unsigned char y;
char z;
/* Code that assigns values to w,x and y. All values assigned
could have been represented by a signed char. */
z = MODULUS((x - y), w);
It is my understanding that the arithmetic (x - y) will be accomplished prior to any type conversion and the macro will always evaluate to (a)%(b) — as the result will be an unsigned char which is always greater than or equal to zero. However, the code functions as intended and I think that my understanding is flawed. So…
My questions are these:
-
Does an implicit type conversion to signed char occur before the expression is evaluated?
-
Is there a situation (for example, if the unsigned values were large enough that they could not be represented by a signed value) where the above code would not work?
No, a conversion to
intoccurs before the expressionx - yis evaluated¹. Thus the result can be negative.If
sizeof int == 1, the integer promotion would promote theunsigned chars tounsigned ints, and that could produce wrong results because before the modulus byw, a modulus byUINT_MAX + 1is performed due to unsigned arithmetic.¹ The default integer promotion.