typedef 的一个常见用途是使变量的“类型”能够更好地传达变量的用途,而无需重新定义其背后的存储结构。
但是,我也将 typedef 视为一次性更改一类变量的存储结构的一种方式。
例如,如果我定义
typedef uint32_t my_offset_t
并具有 my_offset_t
类型的变量,将代码库从 uint32_t
切换到 char
或 uint64_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/