stdc_bit_ceil(3) and wrapping

Alejandro Colomar alx.manpages@gmail.com
Fri Dec 30 21:06:29 GMT 2022


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/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20221230/f3e69976/attachment-0001.sig>


More information about the Gcc mailing list