|
|
Message-ID: <cover.1764193597.git.alx@kernel.org>
Date: Wed, 26 Nov 2025 22:50:20 +0100
From: Alejandro Colomar <alx@...nel.org>
To: musl@...ts.openwall.com
Cc: Alejandro Colomar <alx@...nel.org>
Subject: [PATCH v3 0/1] include/string.h: Implement QChar wrappers
standardized in C23
Hi!
In this v2 revision (see range-diff below), I've changed to use a cast,
as suggested by Rich. __QCharof() remains implemented with _Generic(),
which is the only implementation that we know to work correctly.
Tested:
alx@...uan:~/tmp$ cat strchr.c
#include <stdio.h>
#include <string.h>
int
main(int argc, const char *argv[argc + 1])
{
char *p;
p = strchr(argv[0], 'u');
puts(p);
const char *cp;
cp = strchr(argv[0], 'u');
puts(cp);
&strchr(argv[0], 'u');
strchr(argv[0], 'u') = NULL;
}
alx@...uan:~/tmp$ gcc strchr.c
strchr.c: In function ‘main’:
strchr.c:18:9: error: lvalue required as unary ‘&’ operand
18 | &strchr(argv[0], 'u');
| ^
strchr.c:20:30: error: lvalue required as left operand of assignment
20 | strchr(argv[0], 'u') = NULL;
| ^
alx@...uan:~/tmp$ gcc -I /opt/local/musl/libc/qchar/include/ strchr.c
strchr.c: In function ‘main’:
strchr.c:10:11: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
10 | p = strchr(argv[0], 'u');
| ^
strchr.c:18:9: error: lvalue required as unary ‘&’ operand
18 | &strchr(argv[0], 'u');
| ^
strchr.c:20:30: error: lvalue required as left operand of assignment
20 | strchr(argv[0], 'u') = NULL;
| ^
Have a lovely night!
Alex
Alejandro Colomar (1):
include/string.h: Implement QChar wrappers standardized in C23
include/string.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
Range-diff against v2:
1: 5cd6a281 ! 1: c47e9570 include/string.h: Implement QChar wrappers standardized in C23
@@ Metadata
## Commit message ##
include/string.h: Implement QChar wrappers standardized in C23
- I used compound literals instead of casts because they're less
- dangerous. They only allow conversions that would be legal implicitly.
-
- The register storage-class specifier is used because compound literals
- are lvalues. register makes sure one can't take the address of them.
- That is, it rejects:
-
- &strchr(s, c);
-
Signed-off-by: Alejandro Colomar <alx@...nel.org>
## include/string.h ##
@@ include/string.h: size_t strlen (const char *);
char *strerror (int);
+#if __STDC_VERSION__ >= 202311L
-+# define strchr(s, ...) ((register __QCharof(s) *){ strchr(s, __VA_ARGS__)})
-+# define strrchr(s, ...) ((register __QCharof(s) *){strrchr(s, __VA_ARGS__)})
-+# define strpbrk(s, ...) ((register __QCharof(s) *){strpbrk(s, __VA_ARGS__)})
-+# define strstr(s, ...) ((register __QCharof(s) *){ strstr(s, __VA_ARGS__)})
++# define strchr(s, chr) ((__QCharof(s) *) strchr(s, chr))
++# define strrchr(s, chr) ((__QCharof(s) *) strrchr(s, chr))
++# define strpbrk(s, chrs) ((__QCharof(s) *) strpbrk(s, chrs))
++# define strstr(s, str) ((__QCharof(s) *) strstr(s, str))
+#endif
+
#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
@@ include/string.h: char *strchrnul(const char *, int);
void *memrchr(const void *, int, size_t);
void *mempcpy(void *, const void *, size_t);
+# if __STDC_VERSION__ >= 202311L
-+# define strchrnul(s, ...) ((register __QCharof(s) *){ strchrnul(s, __VA_ARGS__)})
-+# define strcasestr(s, ...) ((register __QCharof(s) *){strcasestr(s, __VA_ARGS__)})
++# define strchrnul(s, chr) ((__QCharof(s) *) strchrnul(s, chr))
++# define strcasestr(s, str) ((__QCharof(s) *) strcasestr(s, str))
+# endif
#endif
--
2.51.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.