On 12/30/22 22:01, Alejandro Colomar wrote: > On 12/30/22 21:56, Joseph Myers wrote: >> On Fri, 30 Dec 2022, Alejandro Colomar via Gcc wrote: >> >>> For the C standard, shifts have wrap around semantics for unsigned types: >> >> Only if the shift count is nonnegative and strictly less than the width of >> the type.  This is about shifting by an amount equal to the width of the >> type, which has undefined behavior. > > Ahhh, right, I forgot that detail.  Yep, I need to special-case then. > > Thanks! > > > This should work, I guess (and hopefully, the compiler will remove the special case in platforms that don't need it): $ cat lib/bit.h #include inline int leading_zerosul(unsigned long x); inline int bit_widthul(unsigned long x); inline int bit_ceil_wrapul(unsigned long x); inline int leading_zerosul(unsigned long x) { return (x == 0) ? ULONG_WIDTH : __builtin_clz(x); } inline int bit_widthul(unsigned long x) { return ULONG_WIDTH - leading_zerosul(x); } /* Similar to stdc_bit_ceilul(), but wrap around instead of UB. */ inline int bit_ceil_wrapul(unsigned long x) { int b; b = bit_widthul(x - 1); return b < ULONG_WIDTH ? 1ul << b : 0; } --