Alejandro Colomar wrote:
> #define __QVoidptrof(p) typeof(1?(p):(void*){0})
>
> #define __QCharptrof(s) typeof \
> ( \
> _Generic((__QVoidptrof(s)){0}, \
> const void *: (const char *) 0, \
> void *: (char *) 0 \
> ) \
> )
>
> #if __STDC_VERSION__ >= 202311L
> # define memchr(p, chr) ((__QVoidptrof(p)) memchr(p, chr))
> # define strchr(s, chr) ((__QCharptrof(s)) strchr(s, chr))
> # define strrchr(s, chr) ((__QCharptrof(s)) strrchr(s, chr))
> # define strpbrk(s, chrs) ((__QCharptrof(s)) strpbrk(s, chrs))
> # define strstr(s, str) ((__QCharptrof(s)) strstr(s, str))
> #endif
>
> I find it quite more readable than the glibc implementation.
Sorry, but I disagree on this "more readable" claim. You take an aggregate
initializer {0} and cast that to 'void *'. What is that meant to be??
Additionally, there are situations where '_Generic' works and 'typeof'
doesn't (namely clang-cl in C++ mode).
So, I vote for a simple use of _Generic.
> I think it would be more reasonable to transform all string APIs to be
> const-generic at once
This is outside the scope of Gnulib. Making strchr etc. const-generic
is the job of the system include files, and is important only on the
developer's main development machine (for getting warnings). It would
be a big effort with little value to make this work on all older
platforms, from AIX to Solaris.
Bruno