Hello,

On Wed, 15 Oct 2025, Alejandro Colomar wrote:

> > Another case where I would expect these macros to be useful is in the
> > implementation of <stdbit.h> APIs.  Do we want to support things like
> > popcount((bool)1)?  The answers are coupled, I think.
> > 
> > For example:
> > 
> >     T
> >     bit_ceil(T x)
> >     {
> >             return 1 + (_Maxof(T) >> leading_zeros(x));
> >     }

FWIW, this converts to T on return, ...

> And I don't think we want to support bool in <stdbit.h>.  It doesn't
> behave like all the other unsigned integer types:
> 
>       alx@devuan:~/tmp$ cat bc.c 
>       #include <stdbool.h>
>       #include <stdio.h>
> 
>       #define bit_ceil_b(x)   ((bool)1 + ((bool)1 >> (x == 0 ? 1 : 0)))

... while this doesn't.  So it's not equivalent, add an outer cast to bool 
to make it so, and then you'd get:

$ ./a.out
1
0
1
1

which is exactly the difference between wrapping (uint1) vs saturating 
(bool) plus.  As the original expression contains an obvious wrap around 
for x==maxof(T), T's behaviour on overflow matters, and I don't find that 
surprising or sufficiently different to exclude bool from anything where 
it naturally can be assigned meaning.  signed integer types also have 
different behaviour on wrap-around, so to C programmers it shouldn't come 
as a surprise that arithmetic expressions need to be formulated carefully.


Ciao,
Michael.

Reply via email to