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/>

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to