位移位可移植性

Bit shift portability

本文关键字:可移植性      更新时间:2023-10-16

我的问题相当直接,此代码可移植?

#include  <cstdint>
#ifndef  ECS_INT
  #define  ECS_INT  uint32_t
#endif
#ifndef  ECS_MAX_NB_COMPONENTS
  #define  ECS_MAX_NB_COMPONENTS  255
#endif
static constexpr uint8_t  FIND_MAX_NUMBER_OF_BITS(uint64_t base) {
  //! Round to upper pow2
  base--;
  base |= base >> 1;
  base |= base >> 2;
  base |= base >> 4;
  base |= base >> 8;
  base |= base >> 16;
  base |= base >> 32;
  base++;
  //! Check bits number
  uint8_t  counter = 0;
  while (!(base & (1 << counter)))
    ++counter;
  return counter;
}
static constexpr const ECS_INT  INVALID_INDEX           = ((ECS_INT) - 1);
static constexpr const uint8_t  ECS_INT_MAX_BITS        = FIND_MAX_NUMBER_OF_BITS(INVALID_INDEX) + 1;
static constexpr const uint8_t  ECS_COMPONENT_MAX_BITS  = FIND_MAX_NUMBER_OF_BITS(ECS_MAX_NB_COMPONENTS);

我不是对位的专家,但我认为该语言允许这是可移植的。也许我应该使用std::bitset之类的东西?

  • 1 << counter应该是 (uint64_t)1 << counter,否则当counter到达sizeof(int) * CHAR_BIT时,它是未定义的行为(并且在少于一个小时时实现定义)。
  • 即使修复了此操作,循环也将评估某些输入的(uint64_t)1 << 64,即未定义的行为,因此您需要添加预检查或循环条件以防止这种情况。