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