【问题标题】:Typedefs and printf format specifiersTypedefs 和 printf 格式说明符
【发布时间】:2012-05-17 12:06:51
【问题描述】:

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

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

例如,如果我定义

typedef uint32_t my_offset_t

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

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

谢谢!

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

【问题讨论】:

    标签: c typedef format-specifiers


    【解决方案1】:

    这是一项棘手的工作,但来自 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 并且在两者上都能干净地编译。)

    【讨论】:

      【解决方案2】:

      如果您查看我的earlier question on inttypes.h,您会看到系统定义的格式说明符如何与 typedefs 一起使用(通过 #define)为您的自定义类型制作自定义打印说明符。

      【讨论】:

      • 感谢您的回答 :) 我接受了另一个,因为它是一个更完整的回答,以防其他人对此问题感兴趣。
      【解决方案3】:

      另一种解决方案是在intmax_tuintmax_t 之间转换为有符号类型,uintmax_t 用于无符号类型。例如:

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

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

      对于*scanf() 函数,您必须读入一个临时对象,然后进行赋值。

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

      【讨论】:

        猜你喜欢
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        • 2018-10-09
        相关资源
        最近更新 更多