[PATCH v2] Implement C23 const-preserving standard library macros

Paul Eggert eggert@cs.ucla.edu
Wed Nov 19 17:45:15 GMT 2025


On 2025-11-19 09:37, Collin Funk wrote:
> Wouldn't this break a ton of existing code since HAYSTACK is evaluated
> multiple times [1]?

Shouldn't be a problem for correct programs. _Generic doesn't evaluate 
its first argument; it merely uses the argument's type.

There is a problem for incorrect programs: too many diagnostics. For 
example, for strchr (1, 'x') you'll see something like the following. 
Without help from the compiler, though, I don't see how to fix this 
quality-of-implementation issue.

t.c: In function ‘foo’:
t.c:12:23: error: pointer/integer type mismatch in conditional 
expression [-Wint-conversion]
    12 |   _Generic (0 ? (PTR) : (void *) 1,                     \
       |                       ^
t.c:19:3: note: in expansion of macro ‘__glibc_const_generic’
    19 |   __glibc_const_generic (S, const char *, strchr (S, C))
       |   ^~~~~~~~~~~~~~~~~~~~~
t.c:25:11: note: in expansion of macro ‘strchr’
    25 |   return !strchr (1, 'x');
       |           ^~~~~~
t.c:25:19: error: passing argument 1 of ‘strchr’ makes pointer from 
integer without a cast [-Wint-conversion]
    25 |   return !strchr (1, 'x');
       |                   ^
       |                   |
       |                   int
t.c:13:36: note: in definition of macro ‘__glibc_const_generic’
    13 |             const void *: (CTYPE) (CALL),               \
       |                                    ^~~~
t.c:25:11: note: in expansion of macro ‘strchr’
    25 |   return !strchr (1, 'x');
       |           ^~~~~~
In file included from t.c:1:
/usr/include/string.h:246:34: note: expected ‘const char *’ but argument 
is of type ‘int’
   246 | extern char *strchr (const char *__s, int __c)
       |                      ~~~~~~~~~~~~^~~
t.c:25:19: error: passing argument 1 of ‘strchr’ makes pointer from 
integer without a cast [-Wint-conversion]
    25 |   return !strchr (1, 'x');
       |                   ^
       |                   |
       |                   int
t.c:14:22: note: in definition of macro ‘__glibc_const_generic’
    14 |             default: CALL)
       |                      ^~~~
t.c:25:11: note: in expansion of macro ‘strchr’
    25 |   return !strchr (1, 'x');
       |           ^~~~~~
/usr/include/string.h:246:34: note: expected ‘const char *’ but argument 
is of type ‘int’
   246 | extern char *strchr (const char *__s, int __c)
       |                      ~~~~~~~~~~~~^~~



More information about the Libc-alpha mailing list