繁体   English   中英

Typedef和printf格式说明符

[英]Typedefs and printf format specifiers

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

但是,我也看到typedef是一种改变一类变量的存储结构的方法。

例如,如果我定义

typedef uint32_t my_offset_t

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

有没有办法根据类型以一种简单的方式交换格式说明符,没有printf / scanf ,if-elses或ifdefs的包装函数?

谢谢!

对于任何感兴趣的人,我正在修改一个使用16位偏移来处理32位偏移的LKM,但是如果需要的话,希望能够以最小的变化进行64位(或其他!)偏移。

这是一项棘手的业务,但C99及后来的<inttypes.h>显示了这样做的方法。

对于每个定义的类型,您需要为自己提供一组适当的'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并在两者上干净地编译。)

如果您查看我之前关于inttypes.h的问题,您可以看到系统定义的格式说明符如何与typedef(通过#define )一起使用,以便为您的自定义类型创建自定义打印说明符。

另一种解决方案是转换和从intmax_t有符号类型和uintmax_t的无符号类型。 例如:

printf("%ju\n", (uintmax_t)n);

如果n是任何无符号类型,则将正常工作。

对于*scanf()函数,您必须读入临时对象然后分配。

(这假设您的运行时库支持这些功能。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM