Re: [PATCH] Add cast to unsigned char to strverscmp

Christian Franke <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
Hans-Bernhard Bröker wrote:
> Am 08.11.2024 um 18:36 schrieb Christian Franke:
>
>> This variant does not depend on signedness or integer overflow:
>>
>>    if ('1' <= l[dp] && l[dp] <= '9' && '1' <= r[dp] && r[dp] <= '9') {
>
> Or one could actually use isdigit() for what it's intended to do? Yeah 
> right, that would be just too ridiculous to even consider...
>
>

No, because the '0' is intentionally excluded here.

I never use isdigit() in my own code because it forbids to directly pass 
negative signed char values and typically results in unnecessary (locale 
specific) code.

"Proof" for newlib:

int isdigit_slow(int c)
{
   return isdigit(c);
}

int isdigit_fast(int c)
{
   return ('0' <= c && c <= '9');
}

Code generated with 'gcc -O2 ...':

isdigit_slow:
     pushq    %rbx
     subq    $32, %rsp
     movslq    %ecx, %rbx
     call    __locale_ctype_ptr
     movzbl    1(%rbx,%rax), %eax
     andl    $4, %eax
     addq    $32, %rsp
     popq    %rbx
     ret

isdigit_fast:
     xorl    %eax, %eax
     subl    $48, %ecx
     cmpl    $9, %ecx
     setbe    %al
     ret

Speedup factor is somewhere between 5x and 10x.

If compiled as C++ with 'g++ -O2 ...', identical (fast) code is 
generated for both functions. This is because the is*() macros in 
ctype.h are disabled for C++. Then GCC uses its builtin isdigit(). Not 
really consistent, IMO :-)

-- 
Regards,
Christian
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.