例如,此代码已损坏(我刚刚在实际代码中修复了它..)。
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/