在 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 位宽,因此它也是可移植的。
那么,这些宏的用途是什么?
你需要它们在你想确保它们不会变得太宽的地方
#define myConstant UINT32_C(42)
然后
printf( "%" PRId32 " is %s\n", (hasproperty ? toto : myConstant), "rich");
在这里,如果常量是UL表达式,则可ulong变参数函数可能会将一个 64 位的值放在堆栈上,这会被printf.
它们使用宽度至少为 N的最小UINT32_C(42)整数类型,因此仅相当于小于 32 位42UL的系统。int在int32 位或更高位的系统上,UINT32_C(42)等效于42U. 你甚至可以想象一个系统,其中 ashort是 32 位宽,在这种情况下,它UINT32_C(42)等价于(unsigned short)42.
编辑:@obareey 似乎大多数(如果不是全部)标准库的实现不符合标准的这一部分,也许是因为这是不可能的。[ glibc 错误 2841 ] [ glibc 提交 b7398be5 ]
宏本质上可能会在它们的参数中添加一个整数常量后缀,例如
L, LL, U, UL, o UL,这基本上使它们几乎等同于相应的强制转换,除了后缀永远不会向下转换。
例如,
UINT32_C(42000000000)LLP64 架构上的(420 亿)将变成42000000000U,其类型UL受此处解释的规则的约束。另一方面,相应的转换 ( (uint32_t)42000000000) 会将其截断为uint32_t(unsigned int在 LLP64 上)。
我想不出一个好的用例,但我想它可以在一些需要至少 X 位才能工作的通用位旋转宏中使用,但如果用户传入某些东西,我不想删除任何额外的位大。