如何将类型分配给宏定义的数字?

时间:2018-01-17 16:24:50

标签: c macros

一般来说,我有点理解整数文字在宏中是如何工作的。因此,如果我想在宏中定义一些unsigned long,我将生成以下代码:

#define CLOCK_FREQUENCY 16000000UL

这是我对整数文字的一般理解。

然而,我打算做的是在我的宏内部指定一个数字uint32_t。在尝试找到一种方法时,我没有发现任何与uint32_t对应的整数文字。那么,有没有办法将数字实际指定为uint32_t或其他类型(就此而言)整数文字表示法不可用?

3 个答案:

答案 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 long16000000000UL可以是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_tunsigned 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),但这似乎是一个严重的过度杀伤案例。