For educational purposes (yes 42 yes) I'm rewriting strncmp and a classmate just came up to me asking why I was casting my returnvalues in such a way. My suggestion was to typecast first and dereference afterwards. My logic was that I wanted to treat the char string as an unsigned char string and dereference it as such.
int strncmp(const char *s1, const char *s2, size_t n)
{
if (n == 0)
return (0);
while (*s1 == *s2 && *s1 && n > 1)
{
n--;
s1++;
s2++;
}
return (*(unsigned char *)s1 - *(unsigned char *)s2);
}
His was to dereference first and to typecast afterwards in order to make absolutely sure it returns the difference between two unsigned chars. Like this:
return ((unsigned char)*s1 - (unsigned char)*s2);
Following the discussion (and me agreeing with him my casting is weird) we looked up some source code of production-ready implementations and to to our surprise Apple seems to cast/dereference in the same order as I do:
https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/i386.subproj/strncmp.c.auto.html
Therefore the question: what is the difference in this case? And why choose one over the other?
(I've already found the following; but it specifies the casting/dereferencing of datatypes of different sizes whereas in the case of chars/unsigned chars it shouldn't matter right?
In C, if I cast & dereference a pointer, does it matter which one I do first? )
if (n == 0) return (0);
initial test. – Pelagia(n > 1 && *s1 && *s1 == *s2)
. – Garvy