visual studio – C++ – Questions about bit shift operators (>)


Consider the below code:

std::string g_CharTable = "stjkloptrew23456mncv891TZUIOPAS";
std::uint32_t value     = 123456789
std::string hash;

for (std::size_t i = 0; i < 5; ++i)
{
    const std::uint32_t index = ((value >> (24 - (8 * i))) & 0x000000FF) % (std::uint32_t)g_CharTable.length();
    hash.push_back(g_CharTable[index]);
}

If you execute the above code, you should notice that something strange happen in the last iteration. Indeed i will be equal to 4, and the value >> (24 - (8 * i)) will have -8 as result. This means that the the number of bits to shift will exceed the range of an uint32 value.

However this code was working perfectly as long as it was executed under Visual Studio 2019. But when I updated my code to Visual Studio 2022, the last iteration always returned an index of 0, which of course caused an issue in the result of this function. What is strange is that VS2019 was performing the bit shift as if the shifting value was converted to unsigned and a modulo of 32 was applied on it, something like that: ((uint32_t)-8 mod 32) = 24

So my questions are:

  • For an unsigned 32 bit value, is the shifting value limited between 0 and 31, and what should happen if this value is exceeded?
  • What happen e.g. in the following cases:
    • when executing value >> -8?
    • when executing value >> 33?
  • If I try to hardcode a shifting value of -8 or 33, the result I get is always 0, whatever the content of the shifted value (e.g. the result of value >> -8 is 0). However VS2019 accepted to apply a such shifting when it was the result of a calculation. Why? Is it a compiler bug?

Leave a Reply

Your email address will not be published. Required fields are marked *