Very probably yes, but the reasons for it in this case are actually fairly complicated.
unsigned char i = 255;
i++;
The i++
is equivalent to i = i + 1
.
(Well, almost. i++
yields the value of i
before it was incremented, so it's really equivalent to (tmp=i; i = i + 1; tmp)
. But since the result is discarded in this case, that doesn't raise any additional issues.)
Since unsigned char
is a narrow type, an unsigned char
operand to the +
operator is promoted to int
(assuming int
can hold all possible values in the range of unsigned char
). So if i == 255
, and UCHAR_MAX == 255
, then the result of the addition is 256
, and is of type (signed) int
.
The assignment implicitly converts the value 256
from int
back to unsigned char
. Conversion to an unsigned type is well defined; the result is reduced modulo MAX+1
, where MAX
is the maximum value of the target unsigned type.
If i
were declared as an unsigned int
:
unsigned int i = UINT_MAX;
i++;
there would be no type conversion, but the semantics of the +
operator for unsigned types also specify reduction module MAX+1
.
Keep in mind that the value assigned to i
is mathematically equivalent to (i+1) % UCHAR_MAX
. UCHAR_MAX
is usually 255
, and is guaranteed to be at least 255
, but it can legally be bigger.
There could be an exotic system on which UCHAR_MAX
is too be to be stored in a signed int
object. This would require UCHAR_MAX > INT_MAX
, which means the system would have to have at least 16-bit bytes. On such a system, the promotion would be from unsigned char
to unsigned int
. The final result would be the same. You're not likely to encounter such a system. I think there are C implementations for some DSPs that have bytes bigger than 8 bits. The number of bits in a byte is specified by CHAR_BIT
, defined in <limits.h>
.
CHAR_BIT > 8
does not necessarily imply UCHAR_MAX > INT_MAX
. For example, you could have CHAR_BIT == 16
and sizeof (int) == 2
i.e., 16-bit bytes and 32 bit int
s).