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;
我根本不打扰后缀。
为什么我在初始化时需要这些宏?
答案 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