|
|
Message-ID: <20251127170546.GA1827@brightrain.aerifal.cx> Date: Thu, 27 Nov 2025 12:05:46 -0500 From: Rich Felker <dalias@...c.org> To: Markus Wichmann <nullplan@....net> Cc: musl@...ts.openwall.com, Alejandro Colomar <alx@...nel.org> Subject: Re: [PATCH v2 1/1] include/string.h: Implement QChar wrappers standardized in C23 On Thu, Nov 27, 2025 at 04:01:56PM +0100, Markus Wichmann wrote: > Am Wed, Nov 26, 2025 at 04:18:25PM -0500 schrieb Rich Felker: > > Hmm, maybe it doesn't work. It looks like only exactly (void *)0 is a > > null pointer constant. A cast to a qualified void pointer type isn't > > one. I'm not sure if it's fixable. > > > > Rich > > There really is no expression that turns void* into char*, or at least > not that I could find. But it is possible to simplify the generic > expression Alejandro is using: > > #define _QChar(s) typeof(_Generic(1?(s):(void *)"", void *: (char *)0, const void *: (const char *)0)) > #define strstr(s, c) ((_QChar(s))strstr(s, c)) > > Feel free to reformat as you like. > > The controlling expression of the generic is compatible with all pointer > types, and always becomes a void* or const void*. This means it already Strictly speaking it could also become a pointer to a worse-qualified version of void like const restrict volatile void *. Of course passing a such-qualified pointer is a constraint violation already so it doesn't matter here. > has the correct type for the mem* functions and bsearch(), once you > start looking at those. For the str* functions, the only way I see to > get from those to char* is the generic expression. > > The idea is to use an expression to query the const qualifier only. > According to the rules for conditional operators, I will get an equally > qualified void pointer only if the third expression is a non-null void > pointer (I would get the original type of s if it were a null pointer > constant). The simplest non-null pointer I can find is a string > literal. > > I think it is better to let the const correctness macro only handle the > return value, because it leads to better error messages. With > Alejandro's current attempt, something like > > int *p; > strstr(p, ""); > > will lead to an error message about no case existing for int* in the > generic expression, whereas my solution will leave the original error > message the compiler would generate from initializing a const char * > from an int * in place. I like this a lot better, for all the reasons you explained on top of it being simpler. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.