ok sorry i should not post at all .. i realized in the meantime this C23 was on the table at first long ago, by Rene Kita, already.. but
Alejandro Colomar via Mutt-dev wrote in <aeDEw-PCa6n1P_4R@devuan>: .. |I've implemented a patch for musl (which hasn't been merged yet). |It only needs C11 features. This is very (, very) cool. |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__)) That __Qvoidptr() really is magic to me. I still do not get it, and your "how" did not give any glue. So i searched and found at [1] (linked from [2]) // fmt.h requires C11 _Generic and the GNU __typeof__ extension, which means // it's compatible with gcc, clang, and tcc, but not e.g. MSVC. .. // (__typeof__(x)[]{x}) is a problem when x is a string literal, because the // type of a string literal is (char[]) rather than (char *). Trigger decay // explicitly. In gcc you can use __typeof__((void)0,(x)), but that's not // compatible with tcc, so I'm using __typeof__(1 ? (x) : (x)) instead. // (TODO: Report this GNU incompatibility to tcc?) #define FMT_ARG(x) \ ((FmtArg){(__typeof__((1 ? (x) : (x)))[]){(x)}, FMT_MAKE_FMTTYPE(x)}) #define FMT_ARG_END ((FmtArg){0,0}) And i remembered some (lesser interesting) email from the tcc list [3] that had "_Generic(t, __typeof__( ((void)0,(T){0})) : 1 );" [1] https://slbkbs.org/tmp/fmt/fmt.h [2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2593.htm [3] https://lists.nongnu.org/archive/html/tinycc-devel/2024-01/msg00000.html But that __Qvoidptr() totally escapes me. Ie decay (Joy Division is greeting) back and forth, i must specify a compatible pointer type, and no matter whether i say typeof(true ? x : y) or typeof(false ? x : y) or the order of x and y, i will always get a "void [const]*". I mean, "all pointer types implicitly convert to void*". But it is total magic! --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
