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

Reply via email to