Understanding the strcmp function of gnu libc

前端 未结 2 2018
误落风尘
误落风尘 2021-01-06 05:34

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         


        
2条回答
  •  渐次进展
    2021-01-06 06:21

    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.

提交回复
热议问题