c - Typedef 和 printf 格式说明符

标签 c typedef format-specifiers

typedef 的一个常见用途是使变量的“类型”能够更好地传达变量的用途,而无需重新定义其背后的存储结构。

但是,我也将 typedef 视为一次性更改一类变量的存储结构的一种方式。

例如,如果我定义

typedef uint32_t my_offset_t

并具有 my_offset_t 类型的变量,将代码库从 uint32_t 切换到 charuint64_t就像更改一行并重新编译一样简单(假设我使用的是 sizeof 而不是硬编码的大小),printf/scanf 除外

有没有一种方法可以根据类型以某种简单的方式交换格式说明符,而无需围绕 printf/scanf、if-elses 或 ifdefs 的包装函数?

谢谢!

对于任何感兴趣的人,我正在修改一个使用 16 位偏移量以使用 32 位偏移量的 LKM,但希望它能够转到 64 位(或其他东西!)偏移量,如果需要进行最少的更改。

最佳答案

这是一件棘手的事情,但是 <inttypes.h>来自 C99 及更高版本显示了执行此操作的方法。

对于您定义的每个类型,您需要为自己提供一组适当的“PRI”和“SCN”宏,注意避免标准化命名空间。

例如,您可以使用 XYZ 作为项目特定的前缀,并产生:

XYZ_PRIx_my_offset_t
XYZ_PRId_my_offset_t
XYZ_PRIX_my_offset_t
XYZ_PRIu_my_offset_t
XYZ_PRIo_my_offset_t

和 SCN 等价物。此外,您将根据基本类型的等效宏来定义它们,因此:

#define XYZ_PRIx_my_offset_t PRIx32
#define XYZ_PRId_my_offset_t PRId32
#define XYZ_PRIX_my_offset_t PRIX32
#define XYZ_PRIu_my_offset_t PRIu32
#define XYZ_PRIo_my_offset_t PRIo32

在您的代码中,您使用 XYZ_PRIx_my_offset_t 构建格式字符串宏:

printf("Offset: 0x%.8" XYZ_PRIX_my_offset_t "\n", my_offset_value);

如果您随后需要将所有内容更改为 64 位,您可以适本地编辑 typedef 和宏定义,其余代码保持“不变”。如果您真的很小心,您几乎可以完全保持不变。

确保在 32 位和 64 位系统上编译并设置了很多警告。 GCC 不会警告您当前平台上的非问题,但它们可能会出现在另一个平台上。 (我刚刚修复了一些在 64 位上干净但在 32 位上不干净的代码;它现在使用类似 XYZ_PRId_int4 的宏而不是 %d,并且在两者上都能干净地编译。)

关于c - Typedef 和 printf 格式说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10508236/

相关文章:

c++ - 超线程 - 我可以通过哪个测试来检查它是启用还是禁用?

C 指针算术异常行为

c++ - 指向结构的指针的 Typedef 等价

c - %p c 中的格式说明符

c - 没有参数的 `printf("%p")` 是什么意思

python - 线性插值。如何在 C 中实现此算法? (给出Python版本)

c - lua中的 "dofile"和C API中的 "luaL_dofile"有什么区别?

c - C 中的 typedef struct 问题(非法使用此类型作为表达式)

gcc - G++ 错误 : ‘<anonymous>’ has incomplete type

c - 奇怪的 C fprintf 格式符号