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