c++ - 移位可移植性

标签 c++ bit-manipulation 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对于某些输入,这是未定义的行为,因此您需要添加预检查或循环条件以防止出现这种情况。

关于c++ - 移位可移植性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963792/

相关文章:

c# - 如何确定一个位序列是正数还是负数

java - 数组中多数元素的位操作解决方案

performance - 用于二进制相关的SSE向量的Popcount吗?

c++ - 如何在 QGroupBox 的角上放置图像 - StyleSheet

c++ - Clang 警告 "-Wsigned-enum-bitfield"的含义

c - 编写可移植 C 时要考虑什么?

c - 如果我选择首先在 Linux 上进行开发,我该如何进行跨平台开发?

c++ - 如何强制我的应用程序只打开一个 exe? qt, linux

c++ - 与 "math.h"的链接错误 - 告诉链接器与其链接的选项是什么?

c++ - 如何跨项目读取预定义(#define)?