Implement C23 const-preserving standard library macros
Paul Eggert
eggert@cs.ucla.edu
Wed Nov 19 00:22:11 GMT 2025
On 2025-11-18 13:27, Joseph Myers wrote:
> +#if __HAVE_GENERIC_SELECTION
> +/* If PTR is a pointer to const, return CALL cast to type CTYPE,
> + otherwise return CALL. Pointers to types with non-const qualifiers
> + are not valid. This should not be defined for C++, as macros are
> + not an appropriate way of implementing such qualifier-generic
> + operations for C++. */
> +# define __glibc_const_generic(PTR, CTYPE, CALL) \
> + _Generic (0 ? (PTR) : (void *) 1, \
Any reason this is (void *) 1 and not (void *) 0? I worry some compilers
might diagnose the (void *) 1.
> + const void *: (CTYPE) (CALL), \
> + void *: (CALL))
> +#endif
With GCC this turns some warnings into errors. For example:
int
foo (char volatile *p)
{
return !strchr (p, 'x');
}
is currently a warning, but would become an error. To avoid this
problem, you can change "void *: (CALL)" to "default: (CALL)". Or
better, to "default: CALL" since the parentheses are unnecessary.
One other thing might be worth mentioning. GCC bug 68193 and Clang bug
25764 mean that uses of this macro might generate duplicate diagnostics
for GCC < 14 and for all Clang versions. This is something we ran into
in Gnulib; see its file lib/intprops-internal.h. I don't know how to
work around this glitch, other than by not using _Generic. It may not be
worth working around as the problem merely causes duplicate diagnostics.
https://gcc.gnu.org/PR68193
https://github.com/llvm/llvm-project/issues/25764
More information about the Libc-alpha
mailing list