使用宏来为整数常量初始化对象

时间:2016-11-03 16:13:04

标签: c macros integer c11

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf 7.20.4引入宏整数常量

  

1以下类似函数的宏扩展为整数常量   适合初始化具有整数类型的对象   对应于< stdint.h>中定义的类型。每个宏名称   对应于7.20.1.2或7.20.1.5中类似的类型名称。

我不太明白这一段。 宏基本上将相应的后缀打到未填充的数字上,如:

UINT64_C(0x123) => 0x123ULL

但如果我想初始化uint64_t,我会这样做:

uint64_t x = 0x123; 

我根本不打扰后缀。

为什么我在初始化时需要这些宏?

2 个答案:

答案 0 :(得分:3)

这个UINT64_C(0x123)宏创建一个立即无符号长long数,因此可以在变量参数函数中用于实例或中间计算,而无需转换为uint64_t类型,其中重要的是使用此特定数据类型。

示例:

printf("%llu\n",UINT64_C(0x123));

是正确的

printf("%llu\n",0x123);

不正确且是UB,因为数据大小不正确,printf无法知道。

当你执行uint64_t x = 0x123;时,会有一个赋值和一个隐式转换,所以不需要这样做(printf("%llu\n",x);是正确的)

另一种用法是在中间计算中,如下所示:

uint32_t a = 0xFFFFFFFF;
uint64_t x = a + UINT64_C(0xFFFFFFFF);

不会溢出而

x = a + 0xFFFFFFFF;

将溢出,因为中间结果存储在uint32_t

总之,UINT64_C(SOME_CONSTANT)(uint64_t)SOME_CONSTANT之间的主要功能差异在于,如果值溢出,您将在第一种情况下得到警告,并且在第一种情况下会出现“转换”其他情况(可能是警告,但这取决于编译器)。

答案 1 :(得分:0)

使用u64,您可以告诉您需要64位整数。有些平台通过unsigned long long定义unsigned long,其他平台定义uint64_t ex = 0x123;。如果您的值要与需要此信息的函数(例如printf和pals)进行互操作,则应该处理此间接寻址以获得灵活的代码。 在您的示例中(int)类型具有此信息,无需显式调用宏。但我假设您需要所有64位,如果它超过UL值,您应该拥有ULL / unsigned ex = 0x100000000U; // warning: large integer implicitly truncated to unsigned type [-Woverflow] 后缀。例如:

exporting.buttons.contextButton.menuItems