Here is the strcmp function that i found in the glibc:
int
STRCMP (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned
You're correct of course. One of the casts should be sufficient. Especially if the pointer is cast, casting the retrieved value is a no-op.
Here is the x86-64 compiled with gcc -O3 for the one with unnecessary cast:
STRCMP:
.L4:
addq $1, %rdi
movzbl -1(%rdi), %eax
addq $1, %rsi
movzbl -1(%rsi), %edx
testb %al, %al
je .L7
cmpb %dl, %al
je .L4
subl %edx, %eax
ret
.L7:
movzbl %dl, %eax
negl %eax
ret
and here's the one without the unnecessary cast:
STRCMP:
.L4:
addq $1, %rdi
movzbl -1(%rdi), %eax
addq $1, %rsi
movzbl -1(%rsi), %edx
testb %al, %al
je .L7
cmpb %dl, %al
je .L4
subl %edx, %eax
ret
.L7:
movzbl %dl, %eax
negl %eax
ret
They're identical
However there is one gotcha, that is now mostly of historical interest. If char is signed and the signed representation is not two's complement,
*(const unsigned char *)p1
and
(unsigned char)*p1
are not equivalent. The former reinterprets the bit pattern, while the latter converts the value using modulo arithmetic. This is of only historical interest since not even GCC supports any architecture that doesn't have 2's complement signed representation. And it is the compiler with most ports.