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