stdc_bit_ceil(3) and wrapping

Alejandro Colomar
Fri Dec 30 22:33:01 GMT 2022

Hi Yann,

On 12/30/22 21:33, Alejandro Colomar wrote:
> On 12/30/22 21:18, Yann Droneaud wrote:
>> What's wrong with the following ?


>>      unsigned long max = upper_bound - 1;
>>      unsigned long mask = ULONG_MAX >> __builtin_clzl(max);
> I hate coding these magic operations out of a function, when I can give it a 
> meaningful name.  That reads to me as a magic trick that many maintainers that 
> read it after me will blame me for having to parse it.
> Moreover, it requires you to have the special case for 0 at the top, which I 
> don't want.

I reconsidered; my -1 was equally magic.  And by calling it 'mask',
ULONG_MAX >> n is something not so magic.

The builtin still has the problem that it requires special-casing 0, so I prefer 
the C23 call, which provides the behavior I want for 0:

unsigned long
shadow_random_uniform(unsigned long upper_bound)
	unsigned long  r, max, mask;

	max = upper_bound - 1;
	mask = ULONG_MAX >> leading_zerosul(max);

	do {
		r = shadow_random();
		r &= mask;  // optimization
	} while (r > max);

	return r;

And, now I don't need to add a wrapper around bit_ceil() that removes the UB. 
stdc_leading_zerosul() is just fine for this use case.



-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <>

More information about the Gcc mailing list