一般来说,我有点理解整数文字在宏中是如何工作的。因此,如果我想在宏中定义一些unsigned long
,我将生成以下代码:
#define CLOCK_FREQUENCY 16000000UL
这是我对整数文字的一般理解。
然而,我打算做的是在我的宏内部指定一个数字uint32_t
。在尝试找到一种方法时,我没有发现任何与uint32_t
对应的整数文字。那么,有没有办法将数字实际指定为uint32_t
或其他类型(就此而言)整数文字表示法不可用?
答案 0 :(得分:2)
如何将类型分配给宏定义的数字?
对于uint32_t
,请使用由@dasblinkenlight
施法有陷阱。
当unsigned
为16位时,演员可以缩小常量,如下所示。由于编译器假定程序员是正确的,因此强制转换可能不会生成有关此的警告。
// Becomes 9216 on a 16-bit `unsigned.
#define CLOCK_FREQUENCY ((unsigned) 16000000)
带有<stdint.h>
的为最小宽度整数常量提供宏。我发现((uint32_t)16000000)
更喜欢
以下结果为uint_least32_t
,与uint32_t
通常相同。
UINT32_C(16000000)
当需要容纳常量的类型时,通常不使用强制转换。
#define CLOCK_FREQUENCY 16000000U
当需要特定类型时,施放是一个好主意。
#define CLOCK_FREQUENCY ((uint32_t) 16000000U)
如果需要的类型至少类型的宽度,则更具异性。
#define FOO 16000000000U
#define CLOCK_FREQUENCY (((uint32_t) 1) * FOO)
注意:
在C中,16000000UL
不是文字,而是常量。 Literals 可以获取其地址。
此外,L
中的16000000UL
仅用于扩展常数,在这种情况下至少为unsigned long
。使用long
作为64位,可能不需要扩展。
16000000U
足以形成一个尽可能宽的常数。
UL
不会将常量强制为unsigned long
,而只会至少 unsigned long
。 16000000000UL
可以是unsigned long long
类型。
答案 1 :(得分:1)
您可以定义一个包含所需类型转换的宏,如下所示:
#define CLOCK_FREQUENCY ((uint32_t)16000000)
这使您可以完全避免使用整数文字表示法。
答案 2 :(得分:1)
该标准在<stdint.h>
中为该作业提供了宏:
C11 7.20.4.1最小宽度整数常量的宏
¶1宏
INTN_C(value)
将扩展为整数常量表达式 对应于int_leastN_t
类型。宏UINTN_C(value)
将扩展 到对应于类型uint_leastN_t
的整数常量表达式。对于 例如,如果uint_least64_t
是unsigned long long int
类型的名称, 然后UINT64_C(0x123)
可能会扩展为整数常量0x123ULL
。
这意味着你可以写:
#define CLOCK_FREQUENCY UINT32_C(16000000)
优点是uint_least32_t
保证存在uint32_t
不能保证存在的地方。缺点是uint_least32_t
可能与uint32_t
的类型不同(但只有在没有uint32_t
的情况下才会发生这种情况,因此您的代码可能因为您的常量而无法编译即使你设法直接使用uint32_t
也是如此。我想你可能会修改(uint32_t)UINT32_C(16000000)
,但这似乎是一个严重的过度杀伤案例。