1

Some data are stored in a 64 bit integer. As you can see, inside the getDrvAns function I check if the bit in the position drvIdx-1 is 0 or 1. One cannot be sure if the drvIdx will have a value in the right range (1-64). However, I noticed that if we put a value higher that 64, we have a wrap-around effect as demonstrated in the code below.

My question is, is this a standard behavior? Is it safe to leave it as it is without boundary checks?

Note: If the bit is set to 0 the drive has answered.

uint64_t mDrvAns = 48822;

bool getDrvAns(int drvIdx) {
  std::bitset<64> bitRepOfmDrvAns{mDrvAns};
  return (bitRepOfmDrvAns[drvIdx - 1] != 0ull);
};

std::string yesOrNo(bool val) {
  return ((val==false) ? "Yes" : "No");
}

int main()
{
  int drvIdx = 1;
  std::bitset<64> bitsOfDrvAns{mDrvAns};
  std::cout << bitsOfDrvAns << std::endl;
  std::cout << "Has drv " << drvIdx << " answered? " << yesOrNo(getDrvAns(drvIdx))
        << std::endl;
  drvIdx = 65;
  std::cout << "Has drv " << drvIdx << " answered? " << yesOrNo(getDrvAns(drvIdx))
        << std::endl; 
  return 0;
}
AngelosFr
  • 115
  • 1
  • 9
  • https://en.cppreference.com/w/cpp/utility/bitset/operator_at – Useless Nov 19 '21 at 12:37
  • Right, it's undefined behavior. Thanks, next time I first take a look on cppreference. – AngelosFr Nov 19 '21 at 12:39
  • It may have happened that function parameter `drvIdx` was located in memory right before your bitset, so you got this "always equal" behaviour. But, as everyone else said, it's UB. – Yksisarvinen Nov 19 '21 at 12:43
  • And I guess it is the same UB in statements like this ```mDrvAns |= (1ull << (drvIdx - 1));``` right? – AngelosFr Nov 19 '21 at 12:46

1 Answers1

1

According to the documentation, out of bounds access using operator[] is Undefined Behaviour. Don't do it.

If you don't want to check the bounds yourself, call test() instead, and be prepared to handle the exception if necessary.

Useless
  • 64,155
  • 6
  • 88
  • 132