关于C#:“最小宽度整数常量的宏”的用途是什么

 2020-11-26 

What is the purpose of “Macros for minimum-width integer constants”

在C99标准第7.18.4.1节"最小宽度整数常量的宏"中,一些定义为[U]INT[N]_C(x)的宏用于将常量整数转换为N = 8、16、32、64的最小数据类型。为什么这些宏自I 可以改用L,UL,LL或ULL修饰符? 例如,当我想使用至少32位无符号常量整数时,我可以简单地写42UL而不是UINT32_C(42)。 由于长数据类型至少为32位宽,因此它也是可移植的。

那么,这些宏的目的是什么?


您需要在想要确保它们不会变得太宽的地方使用它们

1
#define myConstant UINT32_C(42)

然后

1
2
printf("%" PRId32" is %s\
"
, (hasproperty ? toto : myConstant),"rich");

在这里,如果常量为UL,则表达式可能为ulong,可变参数函数会将64位值放在栈中,而该值会被printf误解。


它们使用宽度至少为N的最小整数类型,因此UINT32_C(42)仅等效于int小于32位的系统上的42UL。在int为32位或更大的系统上,UINT32_C(42)等效于42U。您甚至可以想象一个short为32位宽的系统,在这种情况下UINT32_C(42)将等效于(unsigned short)42

编辑:@obareey似乎大多数(如果不是全部)标准库的实现不符合标准的这一部分,也许是因为这是不可能的。 [glibc错误2841] [glibc提交b7398be5]


宏实际上可能会添加一个整数常量后缀,例如
LLLUUL,o UL作为其参数,这基本上使它们几乎等同于相应的强制类型转换,只是后缀不会降低。

例如。,
LLP64体系结构上的UINT32_C(42000000000)(420亿)将变为42000000000U,其类型为UL,但要遵循此处说明的规则。另一方面,相应的强制转换((uint32_t)42000000000)会将其截断为uint32_t(在LLP64上为unsigned int)。

我想不出一个好用例,但我想它可以在某些需要至少X位才能工作的通用位旋转宏中使用,但是如果用户传入某些内容,则不想删除任何多余的位大。