u_char vs char (was: [PATCH] Removed the unsafe ngx_memcmp() wrapper for memcmp(3))
alx.manpages at gmail.com
Tue Nov 8 11:15:51 UTC 2022
On 11/8/22 10:50, Maxim Dounin wrote:
>> Even if it's a bit off-topic, I'm very curious about the reason for using
>> u_char. It definitely requires a lot of extra work compared to 'char *': casts,
>> type-safety, reviewing that code just works when workarounding/disabling the
>> compiler warnings. I'm guessing it was also some workaround for broken old
>> implementations and it has just continued like that for consistency, but am
>> curious if there are other better reasons. Certainly, ASCII characters behave
>> well (at least nowadays) independently of the signedness of char, and usually
>> one doesn't do arithmetic with characters in strings.
> Using signed chars for strings simply does not work as long as you
> consider 8-bit strings. It results in wrong sorting unless you do
> care to compare characters as unsigned, requires careful handling
> of all range comparisons such as "ch <= 0x20", does not permit
> things like "ch < 0x80" or "c >= 0xc0", makes impossible to use
> table lookups such as "basis64[s]" (all snippets are from nginx
> The fact that signedness of "char" is not known adds even more
> fun: you can't really do anything without casting it to either
> unsigned char or signed char.
> In general, using "char" for strings is a well known source of
> troubles at least in the Cyrillic world. Writing the code which
> works with arbitrary chars is tricky and error-prone as long as
> you are doing anything more complex than just calling libc
> functions. On the other hand, casts for external functions can be
> easily abstracted in most cases, and always trivial.
Hmm, yeah, it makes sense. The libc design around char instead of u_char is
broken by design, and the requirement that libc macros need to be called with a
cast (e.g., toupper(3)) shows that.
If nginx does things with chars other than calling libc, it makes a lot of sense
to also use u_char.
Thanks for the rationale! It certainly helps to understand why it was done that
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 833 bytes
Desc: OpenPGP digital signature
More information about the nginx-devel