Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251126211823.GZ1827@brightrain.aerifal.cx>
Date: Wed, 26 Nov 2025 16:18:25 -0500
From: Rich Felker <dalias@...c.org>
To: Alejandro Colomar <alx@...nel.org>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH v2 1/1] include/string.h: Implement QChar wrappers
 standardized in C23

On Wed, Nov 26, 2025 at 04:36:38PM +0100, Alejandro Colomar wrote:
> Hi Rich,
> 
> On Wed, Nov 26, 2025 at 10:02:22AM -0500, Rich Felker wrote:
> > On Wed, Nov 26, 2025 at 03:56:21PM +0100, Alejandro Colomar wrote:
> [...]
> > It doesn't have to be functionally breaking common code in the wild to
> > be breaking the *contract*. You'd not allowed to change them because
> > the specification fixes the signatures in stone.
> 
> Agree.  Given how few functions use QChar in the standard library, and
> how stable the standard library is, typos would be unlikely and would be
> obvious enough that they wouldn't pass any review.
> 
> > > > > > Also, can't __Qcharof just be defined as something like
> > > > > > typeof(1?(s):"") without any fancy _Generic machinery?
> > > > > 
> > > > > This wouldn't accept void*, and these functions should accept void*
> > > > > arguments.
> > > > 
> > > > I was thinking the ternary of char* and void* would produce char*, but
> > > > indeed I'm always wrong about that.
> > > 
> > > You weren't totally wrong.  There's special case where that's true: NULL
> > > 
> > > 	alx@...uan:~/tmp$ cat typeof.c 
> > > 	#include <stdio.h>
> > > 	int
> > > 	main(void)
> > > 	{
> > > 		const char *cc;
> > > 		const void *cv;
> > > 		char *c;
> > > 		void *v;
> > > 
> > > 		_Generic(typeof(1?cc:""), const char *: 0);
> > > 		_Generic(typeof(1?cv:""), const char *: 0);
> > > 		_Generic(typeof(1? c:""),       char *: 0);
> > > 		_Generic(typeof(1? v:""),       char *: 0);
> > > 
> > > 		_Generic(typeof(1?(void *)      0:""), const char *: 0);
> > > 		_Generic(typeof(1?(const void *)0:""),       char *: 0);
> > > 	}
> > > 	alx@...uan:~/tmp$ gcc typeof.c 
> > > 	typeof.c: In function ‘main’:
> > > 	typeof.c:11:18: error: ‘_Generic’ selector of type ‘const void *’ is not compatible with any association
> > > 	   11 |         _Generic(typeof(1?cv:""), const char *: 0);
> > > 	      |                  ^~~~~~
> > > 	typeof.c:13:18: error: ‘_Generic’ selector of type ‘void *’ is not compatible with any association
> > > 	   13 |         _Generic(typeof(1? v:""),       char *: 0);
> > > 	      |                  ^~~~~~
> > > 	typeof.c:15:18: error: ‘_Generic’ selector of type ‘char *’ is not compatible with any association
> > > 	   15 |         _Generic(typeof(1?(void *)      0:""), const char *: 0);
> > > 	      |                  ^~~~~~
> > > 	typeof.c:16:18: error: ‘_Generic’ selector of type ‘const void *’ is not compatible with any association
> > > 	   16 |         _Generic(typeof(1?(const void *)0:""),       char *: 0);
> > > 	      |                  ^~~~~~
> > > 
> > > As you can see, typeof(1?(void*)0:"") produces a char*.  Any other void*
> > > doesn't.  This means that the type of NULL is a magic type different
> > > from void*, but which is compatible with void*.  This is slightly
> > > different from nullptr_t in that _Generic(3) is able to distinguish
> > > nullptr_t form void*, but not the type of NULL from void*, but it's
> > > pretty similar.
> > 
> > typeof(1?"":(typeof(s))0) maybe? I think it works!
> 
> Almost!  It's closer.  :)
> 
> 	alx@...uan:~/tmp$ cat typeof.c 
> 	#include <stdio.h>
> 
> 	#if defined TRY1
> 	# define QCharptrof(s)  typeof(1?s:"")
> 
> 	#elif defined TRY2
> 	# define QCharptrof(s)  typeof(1?"":(typeof(s))0)
> 
> 	#else
> 	# define QCharptrof(s)  typeof(QCharof(s) *)
> 	# define QCharof(s)     typeof                                \
> 	(                                                             \
> 		_Generic(s,                                           \
> 			const char *:  (const char){},                \
> 			const void *:  (const char){},                \
> 			char *:        (char){},                      \
> 			void *:        (char){}                       \
> 		)                                                     \
> 	)
> 	#endif
> 
> 	int
> 	main(void)
> 	{
> 		const char *cc;
> 		const void *cv;
> 		char *c;
> 		void *v;
> 
> 		_Generic(QCharptrof(  cc), const char *: 0);
> 		_Generic(QCharptrof(  cv), const char *: 0);
> 		_Generic(QCharptrof(   c),       char *: 0);
> 		_Generic(QCharptrof(   v),       char *: 0);
> 		_Generic(QCharptrof(NULL),       char *: 0);
> 	}
> 
> 	alx@...uan:~/tmp$ gcc typeof.c 
> 	alx@...uan:~/tmp$ gcc -D TRY1 typeof.c 
> 	typeof.c: In function ‘main’:
> 	typeof.c:4:25: error: ‘_Generic’ selector of type ‘const void *’ is not compatible with any association
> 	    4 | # define QCharptrof(s)  typeof(1?s:"")
> 	      |                         ^~~~~~
> 	typeof.c:31:18: note: in expansion of macro ‘QCharptrof’
> 	   31 |         _Generic(QCharptrof(  cv), const char *: 0);
> 	      |                  ^~~~~~~~~~
> 	typeof.c:4:25: error: ‘_Generic’ selector of type ‘void *’ is not compatible with any association
> 	    4 | # define QCharptrof(s)  typeof(1?s:"")
> 	      |                         ^~~~~~
> 	typeof.c:33:18: note: in expansion of macro ‘QCharptrof’
> 	   33 |         _Generic(QCharptrof(   v),       char *: 0);
> 	      |                  ^~~~~~~~~~
> 	alx@...uan:~/tmp$ gcc -D TRY2 typeof.c 
> 	typeof.c: In function ‘main’:
> 	typeof.c:7:25: error: ‘_Generic’ selector of type ‘const void *’ is not compatible with any association
> 	    7 | # define QCharptrof(s)  typeof(1?"":(typeof(s))0)
> 	      |                         ^~~~~~
> 	typeof.c:31:18: note: in expansion of macro ‘QCharptrof’
> 	   31 |         _Generic(QCharptrof(  cv), const char *: 0);
> 	      |                  ^~~~~~~~~~

Hmm, maybe it doesn't work. It looks like only exactly (void *)0 is a
null pointer constant. A cast to a qualified void pointer type isn't
one. I'm not sure if it's fixable.

Rich

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.