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.