On Thu, Jul 19, 2018 at 02:06:16PM -0500, Qing Zhao wrote:
> > If you expand it as (int) ((unsigned char *)p)[n] - (int) ((unsigned char
> > *)q)[n]
> > then aren't you relying on int type to have wider precision than unsigned
> > char
> > (or unit_mode being narrower than mode)?
>
> do you imply that we should only expand it as (int) ((unsigned char *)p)[n]
> - (int) ((unsigned char *)q)[n] when we are sure
> int type is wider than unsigned char?
Yes.
> > I don't see anywhere where you'd
> > give up on doing the inline expansion on targets where e.g. lowest
> > addressable unit would be 16-bit and int would be 16-bit too.
>
> even on this targets, is char type still 8-bit?
> then int type is still wider than char?
C requires that int is at least 16-bit wide, so the sizeof (int) == sizeof
(char) case is only possible say with 16-bit char and 16-bit int, or 32-bit
char and 32-bit int etc.
> > On targets where int is as wide as char, one would need to expand it instead
> > as something like:
> > if (((unsigned char *)p)[n] == ((unsigned char *)q)[n]) loop;
> > ret = ((unsigned char *)p)[n] < ((unsigned char *)q)[n] ? -1 : 1;
> > or similar or just use the library routine.
>
>
> even when int type is as wide as char, expand it as (int) ((unsigned char
> *)p)[n] - (int) ((unsigned char *)q)[n]
> should still be correct (even though not optimal), doesn’t it?
No. Consider p[n] being e.g. 1 and q[n] being __SCHAR_MAX__ + 3U and 16-bit
int and 16-bit char. Then (unsigned char) 0x0001 < (unsigned char) 0x8002,
so it should return a negative number. But (int) (0x0001U - 0x8002U) is
0x7fff, which is a positive int. Now, if int is 17-bit and char is 16-bit,
this works fine, because is then -0x8001 and thus negative.
The above really works only if int is at least one bit wider than unsigned
char.
Jakub