Re: Minor cleanup after adding more warnings to CFLAGS

Steffen Nurpmeso <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <20260416235343.LZAwFl07@steffen%sdaoden.eu>
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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.