Hi Kevin,

On 2026-04-16T09:16:52+0800, Kevin J. McCarthy wrote:
> On Wed, Apr 15, 2026 at 03:45:01PM +0200, Rene Kita wrote:
> > I played around a bit more and unless we are going to make -Wcast-qual a
> > default warning I don't think it's worth it to fix more warnings coming
> > from that flag.
> 
> Let's not take that step right now.  We've already done some good cleanup
> and fixed bugs in the process
> 
> > If we decide to go all in we should just drop every const where we can't
> > prove that we adhere to it.
> 
> Dropping consts all over in mutt would limit the usefulness of some other
> things, like mutt_b2s(), which returns a const char * because modifying the
> EOS without adjusting dptr results in bugs...
> 
> I'd be interested if we could get a little further along to safety by
> adopting the same mechanism glibc recently did for strchr and the others.  I
> haven't looked into what dark arts were involved.

I've implemented a patch for musl (which hasn't been merged yet).
It only needs C11 features.

You can have a look at it to see how that is implemented:
<https://www.openwall.com/lists/musl/2026/02/23/2>

It's much simpler than the glibc implementation, IMO.

I'll paste here the essentials:

        #define __QVoidptrof(p)  typeof(1?(p):(void*){0})
        #define __QCharptrof(s)  typeof                               \
        (                                                             \
                _Generic((__QVoidptrof(s)){0},                        \
                        const void *: (const char *) 0,               \
                        void *:       (char *) 0                      \
                )                                                     \
        )

        #define memchr(p, ...)      ((__QVoidptrof(p)) memchr(p, __VA_ARGS__))
        #define memmem(p, ...)      ((__QVoidptrof(p)) memmem(p, __VA_ARGS__))
        #define memrchr(p, ...)     ((__QVoidptrof(p)) memrchr(p, __VA_ARGS__))

        #define strchr(s, ...)      ((__QCharptrof(s)) strchr(s, __VA_ARGS__))
        #define strrchr(s, ...)     ((__QCharptrof(s)) strrchr(s, __VA_ARGS__))
        #define strpbrk(s, ...)     ((__QCharptrof(s)) strpbrk(s, __VA_ARGS__))
        #define strstr(s, ...)      ((__QCharptrof(s)) strstr(s, __VA_ARGS__))
        #define strchrnul(s, ...)   ((__QCharptrof(s)) strchrnul(s, 
__VA_ARGS__))
        #define strcasestr(s, ...)  ((__QCharptrof(s)) strcasestr(s, 
__VA_ARGS__))


Have a lovely day!
Alex

> Alternatively, we could create wrappers around those kind of "token"
> functions in mutt that take a string as a parameter and return a pointer
> inside that same const/noconst string back.  Something like:
> 
>   const char *next_foo_const(const char *foo) { ....  ;return foo;}
>   char *next_foo(char *foo) {return (char *)next_foo_const(foo);}
> 
> It still has a cast in the wrapper, but it's controlled, and the caller can
> choose the appropriate function without having to make its own, perhaps more
> dangerous, cast.
> 
> -- 
> Kevin J. McCarthy
> GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA



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

Attachment: signature.asc
Description: PGP signature

Reply via email to