Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用整数常量的宏初始化对象_C_Macros_Integer_C11 - Fatal编程技术网

C 使用整数常量的宏初始化对象

C 使用整数常量的宏初始化对象,c,macros,integer,c11,C,Macros,Integer,C11,7.20.4引入了宏整数常量,包括: 1以下类似宏的函数扩展为整数常量 适用于初始化具有整数类型的对象 对应于中定义的类型。每个宏名称 对应于7.20.1.2或7.20.1.5中的类似类型名称 我不太明白这段话。 宏基本上会在未加后缀的数字上加上适当的后缀,如中所示: UINT64_C(0x123) => 0x123ULL 但如果我想初始化uint64_t,我只需要执行以下操作: uint64_t x = 0x123; 而且我根本就不在乎后缀 为什么我在初始化时需要这些宏?此UINT

7.20.4引入了宏整数常量,包括:

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

我不太明白这段话。 宏基本上会在未加后缀的数字上加上适当的后缀,如中所示:

UINT64_C(0x123) => 0x123ULL
但如果我想初始化uint64_t,我只需要执行以下操作:

uint64_t x = 0x123; 
而且我根本就不在乎后缀

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

UINT64_C(0x123)
宏创建一个立即无符号长-长数字,因此它可以用于变量参数函数中,例如,或中间计算,而无需转换为
UINT64_t
类型,使用此特定数据类型非常重要

例如:

printf("%llu\n",UINT64_C(0x123));
是正确的

printf("%llu\n",0x123);
不正确且为UB,因为数据大小不正确,
printf
无法知道这一点

当您执行
uint64\u t x=0x123时,有一个赋值和一个隐式强制转换,所以不需要这样做(而且
printf(“%llu\n”,x);
是正确的)

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

uint32_t a = 0xFFFFFFFF;
uint64_t x = a + UINT64_C(0xFFFFFFFF);
不会溢出

x = a + 0xFFFFFFFF;
将溢出,因为中间结果存储在
uint32\u t


总之,
UINT64_C(SOME_常量)
(UINT64_t)SOME_常量
之间的主要功能区别在于,如果值溢出,在第一种情况下肯定会得到警告,在另一种情况下会得到“转换”(可能是警告,但这取决于编译器).

对于u64,您告诉我们您想要64位整数。一些平台通过定义
无符号long
来提供它,其他平台通过
无符号long
来提供它。如果您的值要与需要此信息的函数(例如printf和pals)进行互操作,则应处理此间接操作,以获得灵活的代码。 在您的示例中(
uint64\u t ex=0x123;
)类型具有此信息,无需显式调用宏。但是我假设您需要所有的64位,如果它超过
int
值,您应该有
UL
/
ULL
后置。例如:

unsigned ex = 0x100000000U;
// warning: large integer implicitly truncated to unsigned type [-Woverflow]

可能重复:我认为这些宏的引入只是为了克服语言缺陷,即stdint.h类型没有整数文字后缀。有点像inttypes.h中printf的格式说明符。您得到警告是因为赋值,而不是因为后缀。后缀从不向下倾斜。如果您
printf(“%u\n”,0x100000000),您会收到一条关于格式字符串错误(不是截断)的警告。