This is a silly question partly for fun.
I have a "well-defined" (or "saturated"?) bit-mask function
template <unsigned N>
uint32_t mask(uint32_t x) {
const uint32_t MASK = N >= 32 ? ~uint32_t(0) : (uint32_t(1) << N) - 1;
return x & MASK;
}
Expected behavior:
uint32_t x = ~uint32_t(0); // 0xFFFFFFFF
mask<8>(x) => 0x000000FF
mask<24>(x) => 0x00FFFFFF
mask<32>(x) => 0xFFFFFFFF
mask<1234>(x) => 0xFFFFFFFF
But I don't like to have an undefined code uint32_t(1) << 1234
within mask<1234>()
though it is 100% harmless (it shouldn't be evaluated.) I don't want to see compiler warnings.
Why doesn't left bit-shift, "<<", for 32-bit integers work as expected when used more than 32 times?See my update below
Please suggest me some bit-twiddling tricks (and template meta-programming?) to get rid of uint32_t(1) << 1234
.
I have GCC 4.9 that (partially) supports C++14 and is smart enough to do constant folding etc
Update
Quoted from the N4140 draft of the C++14 spec:
5.8 Shift operators [expr.shift]
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
Do you folks have any non-template solution?