7

在 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 位宽,因此它也是可移植的。

那么,这些宏的用途是什么?

4

3 回答 3

7

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

#define myConstant UINT32_C(42)

然后

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

在这里,如果常量是UL表达式,则可ulong变参数函数可能会将一个 64 位的值放在堆栈上,这会被printf.

于 2013-05-03T14:55:46.047 回答
3

它们使用宽度至少为 N的最小UINT32_C(42)整数类型,因此仅相当于小于 32 位42UL的系统。intint32 位或更高位的系统上,UINT32_C(42)等效于42U. 你甚至可以想象一个系统,其中 ashort是 32 位宽,在这种情况下,它UINT32_C(42)等价于(unsigned short)42.

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

于 2013-05-03T17:16:00.930 回答
0

宏本质上可能会在它们的参数中添加一个整数常量后缀,例如 L, LL, U, UL, o UL,这基本上使它们几乎等同于相应的强制转换,除了后缀永远不会向下转换。

例如, UINT32_C(42000000000)LLP64 架构上的(420 亿)将变成42000000000U,其类型UL此处解释的规则的约束。另一方面,相应的转换 ( (uint32_t)42000000000) 会将其截断为uint32_t(unsigned int在 LLP64 上)。

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

于 2017-11-13T18:41:49.813 回答