代码之家  ›  专栏  ›  技术社区  ›  izac89

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

c
  •  2
  • izac89  · 技术社区  · 7 年前

    这似乎是一个愚蠢的问题,会让我损失一些名誉分数,但我仍然渴望得到这个问题的反馈。-

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

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

    #define BIT_0 0x1UL
    #define BIT_1 0x2UL
    

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

    uint32_t func (uint32_t input1);
    

    突然间,它击中了我,尽管这几乎是我和同事们的第二天性 UL (和) ULL )常量后缀和变量使用可移植类型,两者的组合(例如,如果这样的常量将被分配、操作或与可移植变量比较)实际上是错误的,因为第一个概念是不可移植的。( long 在不同的系统上长度不同),第二个是。

    我的问题是——我的启蒙是否错了?这两个概念的结合真的可以很好地进行编程吗?或者我是对的,我们使用这两个概念是因为缺乏知识吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   unwind    7 年前

    不,你没有错。硬编码“abstract”类型的后缀 unsigned long 与使用具有指定宽度的更多具体类型不太兼容。

    有时人们只知道映射,不管怎样,它都可以使其正确,但它不是便携式的或干净的。

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

    • 宏int n _ c应扩展为与类型对应的整数常量表达式。 int_leastN_t (例如) INT32_C(4711) 生成一个与 int32_t )
    • uint也一样 n ()
        2
  •  1
  •   Bogdan N.    7 年前

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

    我将使用以下定义来实现兼容性:

    #define BIT_0 (uint32_t)1U
    

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

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

    阅读代码的人可能知道C语言,但可能不知道神奇的宏。

    edit2:同样,也可以使用标准 国际的 n γ-C 格式:

    #define BIT_0 UINT32_C(1U)
    

    uint32_t x = UINT32_C(1) << n;