On Fri, Sep 26, 2025 at 12:10:06AM +0200, Bruno Haible wrote: > Hi Alejandro,
Hi Bruno,
[...]
> C. Convenience for programmers.
> The benefit is that programmers from different projects should
> recognize the function names because they have seen it in use
> elsewhere.
>
> Your proposal is in category C, and therefore the questions
> "what is the point of this proposal?" and "does it have a positive or a
> negative impact on the C programmers community?" are sensitive to details,
> and need to be re-evaluated each time a detail has changed.
Yes, it's in category C.
[...]
> * With the proposed naming 'strprefix' and 'strsuffix' that return
> pointers (after all, as you noted, 'strchr' and 'strstr' also return
> pointers and don't have a 'p' as third letter), I don't see a positive
> nor a negative impact.
Okay, we can negotiate this one.
> I think that the cases where the programmer wants a pointer (not just
> a bool value) is 10% of the use-cases or less.
That guess is far from my numbers.
Here are the actual numbers in shadow utils. The first column is the
case-sensitive version, and the second column the case-insensitive one.
str* strcase* TOTAL
prefix bool: 56 3 59
prefix ptr: 13 0 13
suffix bool: 2 0 2
suffix ptr: 0 1 1
$ echo 'scale=4; 13 / (59 + 13)' | bc
.1805
$ echo 'scale=4; 1 / (2 + 1)' | bc
.3333
It's around 20% for the prefix, and around 30% for the suffix.
> No positive impact because projects which want readable function names
> will do things like
>
> inline bool str_startswith (const char *s, const char *sub)
> {
> return strprefix (s, sub) != NULL);
> }
> inline bool str_endswith (const char *s, const char *sub)
> {
> return strsuffix (s, sub) != NULL);
> }
I wonder if that's worth it, and if it will be done in a non-negligible
number of projects. People haven't wrapped strchr(3) and strstr(3),
AFAIK.
> and they could have gotten the same result by just slightly different
> inline functions:
>
> inline bool str_startswith (const char *s, const char *sub)
> {
> return strncmp (s, sub, strlen (sub)) == 0;
> }
> inline bool str_endswith (const char *s, const char *sub)
> {
> size_t len = strlen (s);
> size_t n = strlen (sub);
> return len >= n && streq (s + len - n, sub);
> }
The latter is already too difficult to write, IMO. If libc provides
strsuffix() for them to be able to wrap, it's already a win.
> So, what is the point of attempting this standardization if the
> majority of the uses are better expressed with a bool-returning
> function anyway? And where different projects will choose
> different function names? Then you can just as well leave it
> unstandardized.
I suspect (but don't have numbers, precisely because I've never written
a wrapper to differentiate the bool-version) that strchr(3) and
strstr(3) are also most commonly used for boolean questions. Finding
a character or a substring is useful, but not the most common operation.
> * With the proposed naming 'str_startswith', 'str_endswith',
> 'str_prefix_end', 'str_suffix_start', there would be a *positive*
> impact, because
> - programmers will recognize 2 of these function names when
> they are/get familiar with 10 out of 15 other programming languages,
Too bad for me that I only speak C, sh(1), and make(1). :-)
> - programmers get accustomed to understandable identifiers.
>
> Therefore, this one I am willing to give my support to.
>
> > About names from other languages, I don't necessarily like that
> > reasoning. We almost had _Countof() named _Lengthof() because committee
> > members wanted that name from other languages which have it as length.
> > That would have been harmful, as it would have mixed sizes and lengths
> > in string-handling code, promoting off-by-one bugs. In general, I'd
> > take other languages with a pinch of salt.
>
> Sure, I am all for evaluating things on a case-by-case basis.
>
> Would 'str_startswith' be confusing or harmful? I don't think so.
>
> Would 'str_suffix_start' be confusing or harmful? I think less than
> 'strsuffix';
I think the names aren't too bad per se, in isolation. But having both
functions with almost identical behavior, but such different names, can
be confusing. And taking into account <string.h> conversions, it gets
worse.
> a programmer may wonder what the difference between 'strcat'
> and 'strsuffix' is. (The name 'strsuffix' does not include a verb.
> It can mean "test for a suffix" or "find a suffix" or "append a suffix"...)
>
> > Consistency with libc is important too. If I see str_startswith(), I
> > would guess it's a projec-specific API.
>
> Wrong guess, because libc also has identifiers with underscores:
> fe_dec_getround
> atomic_compare_exchange
> atomic_flag_test_and_set
> atomic_flag_test_and_set_explicit
> stdc_first_leading_zero_ull
Not in <string.h>. <string.h> is quite compact in its names.
Those functions you mentioned are in the end of the spectrum, where few
people uses those functions.
One of the benefits of having compact names such as strstr(3) is that
we also have conventions for small variations, such as strcasestr(3) for
a case-independent version of the function. In some cases, we also have
the _l suffix for a version where you specify the locale, etc.
> memset_explicit
This one, while being in <string.h>, is also a niche function. Niche
functions have a tendency to have longer names.
BTW, how about consistency with strcasestr(3) for example? With
strprefix(), you can perfectly add strcaseprefix(). With your proposed
names, they soon get long enough to be uncomfortable to use, apart from
being inconsistent, which makes one need to confirm that they're in the
same category.
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
signature.asc
Description: PGP signature
