移位可移植性

Bit shift portability

我的问题比较直接,这个代码可以移植吗?

#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 时它是未定义的行为(当小于 1 时是实现定义的)。
  • 即使在修复该问题后,循环仍会对某些输入进行 (uint64_t)1 << 64 评估,这是未定义的行为,因此您需要添加预检查或循环条件以防止出现这种情况。