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

标签 c macros integer c11

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf 7.20.4 引入了宏整数常量,其中:

1 The following function-like macros expand to integer constants suitable for initializing objects that have integer types corresponding to types defined in <stdint.h>. Each macro name corresponds to a similar type name in 7.20.1.2 or 7.20.1.5.

这一段我不是很明白。 宏基本上将适当的后缀添加到无后缀的数字上,如:

UINT64_C(0x123) => 0x123ULL

但是如果我想初始化一个 uint64_t,我会这样做:

uint64_t x = 0x123; 

而且我根本不会为后缀烦恼。

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

最佳答案

UINT64_C(0x123) 宏创建一个立即数 unsigned long long,因此它可以用于变量参数函数,例如实例或中间计算,而无需强制转换为uint64_t 类型,使用此特定数据类型很重要。

例子:

printf("%llu\n",UINT64_C(0x123));

是正确的

printf("%llu\n",0x123);

不正确并且是未定义的行为,因为数据大小不正确,而 printf 通常不知道这一点。

当你使用 uint64_t x = 0x123; 时,有一个赋值和一个隐式转换,所以不需要这样做(和 printf("%llu\n",x) ; 是正确的)。

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

uint32_t a = 0xFFFFFFFF;
uint64_t x = a + UINT64_C(0xFFFFFFFF);

将产生完整的 64 位和,而

x = a + 0xFFFFFFFF;

将在 32 位内换行,因为中间结果使用 uint32_t 类型。

UINT64_C(SOME_CONSTANT)(uint64_t) SOME_CONSTANT 的一个区别是,如果 UINT64_C 的值太大,第一种情况将生成一个具有更广泛类型的指定值的常量,第二个将生成一个转换为命名类型的值。这些会导致什么错误以及编译器是否会诊断问题可能取决于上下文。

关于c - 使用整数常量的宏初始化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40406394/

相关文章:

c - 为什么这个使用 malloc 的非常基本的 C 代码会崩溃?

c - "return p ? memcpy(p, s, len) : NULL;"是什么意思?

c# - 在 C# 中使用泛型以避免代码重复

c++ - 检查以确保 argv[1] 是整数 C++

string - 戈兰 : how to sum an array of integers as strings and numbers

c - 数组操作(插入元素)

C - 使用递归在邻接矩阵中进行深度优先搜索

c++ - 在附加包含目录中使用预处理器定义

c++ - 在不使用宏的情况下减少语法 "noise"

mysql - 当我进行 LEFT JOIN 时,我的 SIGNED INT 被转换为 UNSIGNED