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)