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 <limits.h> 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; } -- <http://www.alejandro-colomar.es/>
OpenPGP_signature
Description: OpenPGP digital signature