I have a small positive integer n
, and I use an unsigned integral type to store a mask containing n
bits. Often, there is a need to construct a mask with all n
bits set. For example, if n
is 5, then the mask would be 0b11111u
.
The typical way to construct such a mask is to do the following (this example assumes that the mask uses unsigned
, but it is possible to write something for any unsigned integral type):
unsigned all_set_mask = (1u << n) - 1u;
However, 1u << n
is undefined behaviour if n
is exactly equal to the bit width of the unsigned integral type, as seen from [expr.shift#1]:
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the width of the promoted left operand.
A reasonable interpretation of "construct a mask with all n
bits set" arguably should permit the case when we have exactly as many bits as the bit width of the underlying integral type, and so the typical implementation does not support all reasonable inputs.
Furthermore, on modern processors, the assembly left shift instruction is a no-op when shifting by the bit width, and so all_set_mask
might end up being 0
, which isn't the expected answer in any case.
Is there an standard-compliant way to rewrite it without resorting to an if
-statement or complex bit twiddling? I looked into <bit>
but did not see anything of use there.