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)

Reply via email to