isascii(3) macros and casts

Alejandro Colomar alx@kernel.org
Thu Dec 12 15:48:38 GMT 2024


Hi Paul,

On Wed, Dec 11, 2024 at 09:54:02PM +0100, Alejandro Colomar wrote:
> Hi Paul,
> 
> On Wed, Dec 11, 2024 at 09:50:30PM +0100, Alejandro Colomar wrote:
> > On Wed, Dec 11, 2024 at 12:42:13PM -0800, Paul Eggert wrote:
> > > On 2024-12-11 12:38, Paul Eggert wrote:
> > > >    #define isdigit(x) ((int) {x} - '0' <= 9u)
> > > 
> > > Oh, that should be
> > > 
> > >   #define isdigit(x) ((unsigned int) (int) {x} - '0' <= 9)
> > 
> > LGTM.
> > 
> > > 
> > > to avoid problems with signed integer overflow.
> 
> On the other hand, calling isdigit() with anything that's not a valid
> char or EOF (-1) is already UB (and IMO, should stay as UB), so the
> first approach should be enough, no?

After some experimentation, the second implementation is better, as it
avoids a sign mismatch diagnostic.  See below.

Cheers,
Alex


alx@devuan:~/tmp/glibc$ cat isdigit.c 
#define isdigit_a(x) ((int) {x} - '0' <= 9u)
#define isdigit_b(x) ((unsigned int) (int) {x} - '0' <= 9)

int
main(void)
{
	int b;

	b = isdigit_a(3);
	b = isdigit_b(3);
	return b;
}
alx@devuan:~/tmp/glibc$ cc -Wall -Wextra isdigit.c 
isdigit.c: In function ‘main’:
isdigit.c:1:39: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
    1 | #define isdigit_a(x) ((int) {x} - '0' <= 9u)
      |                                       ^~
isdigit.c:9:13: note: in expansion of macro ‘isdigit_a’
    9 |         b = isdigit_a(3);
      |             ^~~~~~~~~

> 
> Cheers,
> Alex
> 
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20241212/8c5f1460/attachment.sig>


More information about the Libc-alpha mailing list