移位可移植性
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
评估,这是未定义的行为,因此您需要添加预检查或循环条件以防止出现这种情况。
我的问题比较直接,这个代码可以移植吗?
#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
评估,这是未定义的行为,因此您需要添加预检查或循环条件以防止出现这种情况。