在C99标准的第7.18.4.1节“最小宽度整数常量宏”中,一些宏定义为[U]INT[N]_C(x)
,用于将常量整数转换为最小数据类型,其中N = 8,16,32,64。为什么这些宏定义,因为我可以使用L,UL,LL或ULL修饰符代替?例如,当我想使用至少 32位无符号常量整数时,我只需编写42UL
而不是UINT32_C(42)
。由于长数据类型至少为32位宽,因此也是可移植的。
那么,这些宏的目的是什么?
答案 0 :(得分:7)
你需要在你想要确保它们不会变得太宽的地方
#define myConstant UINT32_C(42)
以后
printf( "%" PRId32 " is %s\n", (hasproperty ? toto : myConstant), "rich");
这里,如果常量为UL
,则表达式可能为ulong
,并且可变参数函数可能会在堆栈上放置64位值,而printf
会错误解释该值。
答案 1 :(得分:3)
他们使用宽度至少为N的最小整数类型,因此UINT32_C(42)
仅相当于42UL
小于int
的系统int
32位。在UINT32_C(42)
为32位或更高位的系统上,42U
相当于short
。您甚至可以想象一个UINT32_C(42)
为32位宽的系统,在这种情况下(unsigned short)42
将等同于{{1}}。
编辑:@obareey标准库的大多数(如果不是全部)实现似乎都不符合标准的这一部分,可能是因为它是不可能的。 [glibc bug 2841] [glibc commit b7398be5]
答案 2 :(得分:0)
宏基本上可能会添加一个整数常量后缀,例如
L
,LL
,U
,UL
,o UL
到他们的参数,这基本上使他们几乎等同于相应的演员,除了后缀赢了不要垂头丧气。
如,
LLP64架构上的UINT32_C(42000000000)
(420亿)将变为42000000000U
,其UL
类型将受rules explained here约束。另一方面,相应的演员阵容((uint32_t)42000000000
)会将其截断为uint32_t
(LLP64上的unsigned int
)。
我想不出一个好的用例,但我想它可以在一些需要至少X位才能工作的通用bit-twiddling宏中使用,但是如果用户不想删除任何额外的位传递更大的东西。