When you use unsigned char
, the behavior is fully defined by the C standard:
- C 2018 6.2.6.1 3 says
unsigned char
objects shall be represented with pure binary. A footnote makes it clear that all the bits of an unsigned char
participate in this, so it has no padding bits.
- C 2018 6.2.6.1 4 guarantees we can work with the bytes representing any object using
unsigned char
.
- C 2018 6.2.6.1 1 and 2 allow integer types other than
unsigned char
to have padding bits.
For practical purposes, modern C implementations have largely eliminated the shortcomings this leaves in char
and signed char
types. But, in theory, they can have padding bits (and all the bits in the memory accessed as a char
might not contribute to its value, so writing the same char
value to another memory location might not reproduce all the bits) and they can have multiple representations (bit patterns) that represent the same value (two representations for zero, one with a positive sign bit and one with a negative sign bit). (Integer types generally can also have trap representations, but C 2018 6.2.6.1 5 does not allow for these to have effects with character types.) C 2018 6.2.6.2 3 says a “negative zero” is not necessarily preserved when it is stored in an object; it may become a “normal zero.”
So, in theory, when src[i]
is a char
, it might have a value equal to c
even though the bits in the memory of src[i]
differ from the bits of c
, and therefore the memchr
routine would return an incorrect result.
You are unlikely to encounter such a C implementation in practice, but the end result is that the C standard guarantees the behavior with unsigned char
and does not with char
.