Hi Bruno,

On 2026-02-21T17:48:31+0100, Bruno Haible wrote:
> Alejandro Colomar wrote:
> > Another issue I have with the version you've pushed is that the function
> > seems to return a const-qualified pointer, which means that you can't
> > use it as a callback that works on non-const pointers.
> 
> Nope, in the code I committed, 'strnul' cannot be used as a function
> pointer at all.

Ahh, I misread.  If you don't want to provide the function pointer,
which I think is fine (and maybe even desirable), then I would implement
it as simply as

        #define strnul(s)  strchr(s, '\0')

which works for both C and C++, and unless using a 10-year-old compiler,
produces optimized code.

I think not providing the function is a good default choice for new
functions, given that both glibc and ISO C consider the function to be
obsolescent.  This is from the glibc manual:

        As an obsolescent feature, if the macro is suppressed
        the external function returns @code{char *} regardless.
        The function is also qualifier-generic in C++.

I've CCed Joseph, in case he has an opinion about this.  Joseph, we've
added a strnul(3) function to gnulib.  The implementation is
const-generic, and there's no function fallback at all.  I guess this
should be fine for new APIs.  What are your plans for new APIs in glibc?

> Which, as you acknowledged, matches what glibc does
> for const-generic macros.

> > Functions can not be const-generic in C.  The glibc implementation
> > similarly only works for function calls but not function pointers.

Oh, with this I meant that the glibc implementation doesn't do the
const-generic magic for the function (because it's impossible), not that
it doesn't work at all.  My system glibc is too old, so I can't test it,
but the glibc implementation certainly allows one to take a function
pointer.  Here's the relevant part of the patch:

        @@ -252,6 +256,10 @@ strchr (const char *__s, int __c) __THROW
         #else
         extern char *strchr (const char *__s, int __c)
              __THROW __attribute_pure__ __nonnull ((1));
        +# if __GLIBC_USE (ISOC23) && defined __glibc_const_generic && !defined 
_LIBC
        +#  define strchr(S, C)                                         \
        +  __glibc_const_generic (S, const char *, strchr (S, C))
        +# endif
         #endif
         /* Find the last occurrence of C in S.  */
         #ifdef __CORRECT_ISO_CPP_STRING_H_PROTO

It is a macro that shadows the function in function calls, but calls of
the form (strchr)(s, c) will still access the function, and of course,
function pointers will also use the function.


Cheers,
Alex

-- 
<https://www.alejandro-colomar.es>

Attachment: signature.asc
Description: PGP signature

Reply via email to