结合常数后缀和可移植数据类型

时间:2018-09-25 18:30:51

标签: c

这似乎是一个愚蠢的问题,这会使我失去一些声誉分数,但我仍然渴望收到有关此问题的反馈-

我正在从事的几乎所有项目(嵌入式系统),专有驱动程序或第三方库都包含两个概念:

第一个概念是在常量定义中使用UL后缀(也为UUL),例如:

#define BIT_0 0x1UL
#define BIT_1 0x2UL

第二个概念是将可移植类型用于变量声明和函数参数,例如:

uint32_t func (uint32_t input1);

突然间,它震惊了我,尽管对我和我的同事来说,将UL(和ULL)后缀添加到常量,并对变量使用可移植类型是两者的结合,这几乎是我的第二本能。 (例如,将常量分配给可移植变量,对其进行操作或与之进行比较)实际上是错误的,因为第一个概念是不可移植的(long在不同系统上的长度可能会有所不同),而第二个概念是不可移植的是。

我的问题是这个-我的启示是否错了?这两个概念的结合实际上可以使程序设计更好?还是我是对的,而我们同时使用这两个概念的事实是缺乏知识的结果?

2 个答案:

答案 0 :(得分:2)

不,您没看错。对诸如“ unsigned long”之类的“抽象”类型进行硬编码的后缀与使用具有指定宽度的更具体的类型不太兼容。

有时人们只知道映射,无论如何它都可以使它正确,但是它不那么便携或干净。

有些宏可用于文字,请参见<stdint.h>

  • 宏INT N _C应扩展为与类型int_leastN_t相对应的整数常量表达式(例如,INT32_C(4711)生成与int32_t兼容的常量) 。
  • 与UINT N _C()相同。

答案 1 :(得分:1)

您是对的,它可能会在某些系统上引起问题。

为了兼容性,我将使用以下定义:

#define BIT_0 (uint32_t)1U

编辑:如果要完全兼容,则应放弃定义

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

阅读代码的人可能会懂C语言,但可能不知道魔术宏

EDIT2:同样,也可以使用标准的 INT N _C 格式:

#define BIT_0 UINT32_C(1U)

uint32_t x = UINT32_C(1) << n;