Following my previous question, I need to create a value consisting of a solid range of bits set to 1. I used the following function:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= ((1 << count) - 1) << first;
}
However, as discovered, it didn’t work correctly for count = 32. The outcome of 1 << count in such a case theoretically is undefined behavior (or result), and practically on x86 it’s 1, because shift operand is treated modulo 32.
I want to fix this expression to work correctly for this extreme case also. What’s the most simple/nice/efficient way to do this?
Handling this specific case via branching (if, ?) is kinda simple, though ugly, and I bet it’s inefficient either.
Another way is to promote the shift operand to a greater type (64bit). I mean the following:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= (UINT(unsigned __int64(1) << count) - 1) << first;
}
Is there a better way?
Never assume anything is inefficient unless you can prove it. The if-else may just as well be more efficient on your architecture+OS than the promotion to 64-bit. I don’t think there is any other, sane approach than those two you already posted.
I’d go for the if-else because it documents the intent of handling the extreme case. Promoting to 64-bit doesn’t indicate that intent.