c - 使用 INTXX_C 宏和执行类型转换到文字之间有什么区别?

标签 c casting type-conversion integer stdint

例如,此代码已损坏(我刚刚在实际代码中修复了它..)。

uint64_t a = 1 << 60

它可以被修复为,

uint64_t a = (uint64_t)1 << 60

但后来我的脑子里就闪过了这个念头。

uint64_t a = UINT64_C(1) << 60

我知道 UINT64_C(1) 是一个在 64 位系统中通常扩展为 1ul 的宏,但是它与仅仅进行类型转换有何不同?

最佳答案

没有明显的区别或优势,这些宏有点多余。类型转换和宏之间存在一些细微的差别:

  • (uintn_t)1 用于预处理器目的可能会很麻烦,而 UINTN_C(1) 会扩展为单个 pp token 。

  • UINTN_C 的结果类型实际上是 uint_leastn_t 而不是 uintn_t。所以它不一定是您期望的类型。

  • 如果您在代码中键入 1 而不是 1u,适用于 MISRA-C 等编码标准的静态分析器可能会提示,因为移位有符号整数不是一个简单的操作。无论其大小如何,都是绝妙的主意。
    (uint64_t)1u 符合 MISRA 标准,UINT64_c(1) 可能不符合,或者至少分析器无法判断,因为它无法扩展 pp token 就像编译器一样。而且 UINT64_C(1u) 可能不起作用,因为这个宏实现可能看起来像这样:

    #define UINT64_C(n) ((uint_least64_t) n ## ull)
    // BAD: 1u##ull = 1uull
    

一般来说,我建议使用显式强制转换。或者更好地将所有这些包装在一个命名常量中:

#define MY_BIT ( (uint64_t)1u << 60 )

关于c - 使用 INTXX_C 宏和执行类型转换到文字之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70667518/

相关文章:

c - 在 C 中将匿名结构作为参数传递

c - 该程序的返回值为。 。 。 .至少可以说很奇怪

c++ - 如何在运行时检查类型?

types - 为数字提供显式类型

c - 在C中将字符串转换为整数的递归函数

c++ - 如何从 C/C++ 获取虚拟大小?

c++ - 可以对内置类型使用 C 样式转换吗?

lua - 在 Lua 4 中将十进制转换为十六进制?

generics - 将 TypeRep 转换为具体的类型表示

c - 在指向整数数组的指针中使用 scanf