C 语言中的可移植 BIT 宏



我有一个裸机软件环境,可以在多个架构上运行,例如ARM 32-bit v7/ARM 64-bit v8和自定义的内部架构:我们称之为ARCHX

首先如何在ARM32ARM64ARCHX上定义不同的数据类型:

(注意:ARM64在此示例中使用LP64编程模型)。

  • ARM32/ARM64/ARCHX 国际: 32/
    • 32/16
    • 长: 32/
    • 64/32
    • 指针: 32/64/16

我已经实现了一个位宏:

#define BIT(n) (0x1U << (n))

现在ARCHX如果在 int 上使用BIT(ARCHX中的 16 位),这会给出一个错误:

警告:班次计数太大,结果未定义

现在,向此宏添加UL可以解决此问题,但通常可能会导致其他体系结构出现问题。

所以我的问题是:

BIT宏的这个定义是否不能在架构和编译器之间移植,因为我需要在某些架构上使用UL,在某些架构上使用U,甚至在某些组合上使用ULL(ARM64LLP编程模型?

也许BIT宏应该重命名并分为BIT16BIT32BIT64,并按体系结构实现,而不是所有体系结构的通用BIT宏?

首先,绝对没有理由使用这样的宏来隐藏非常基本的功能。x |= 1U << n;比晦涩的x |= BIT(n);清晰得多.始终假设阅读您的代码的人知道 C 语言,但不了解您的秘密宏语言。

因此,您应该做的第一件事是摆脱宏。


话虽如此,可移植性是通过使用stdint.h的类型来实现的。

uint32_t x = (uint32_t)1U << n;

完全可移植到任何已知的计算机。

同样,您也可以使用标准UINTn_C文字格式和类型

uint32_t x = UINT32_C(1) << n;

UINT32_C宏可用于使可移植的无符号 32 位常量。

#include <stdint.h>
#define BIT(n) (UINT32_C(1) << (n))    
int main(void)
{
return BIT(10);
}

您可以通过针对不同平台的配置定义来解决此问题。 比方说

#ifdef SYSTEM_A
#define BIT_BASE_VALUE 0x1U
#else
#ifdef SYSTEM_B
#define BIT_BASE_VALUE 0x1UL
#endif
#endif
#define BIT(n) (BIT_BASE_VALUE << (n))

相关内容

  • 没有找到相关文章

最新更新