使用令牌粘贴来打印十六进制数字的类型相关宏?

Type dependent macro for printfing hex numbers using token pasting?

我想使用相同的宏来打印不同的类型:

int64_t q64 = 0x1234567890ABCDEF;
int32_t q32 = 0x12345678;
int16_t q16 = 0x1234;

PRINT_Q(64, q64);
PRINT_Q(32, q32);
PRINT_Q(16, q16);

(还有一个抽象的“层”,所以我最终得到了普通的 PRINT_Q(name) 宏,而不必指定 64、32 或 16,但让我们在这里简化一下。)

这是一个宏,我想简化一下:

#define PRINT_Q(MAXSIZE, name)                              \
    {                                                       \
        if(MAXSIZE==64)                                     \
            printf(" 0x%.016lX ", name);                    \
        else if(MAXSIZE==32)                                \
            printf(" 0x%.08X ", name);                      \
        else if(MAXSIZE==16)                                \
            printf(" 0x%.04X ", name);                      \
    }

有没有办法避免 if-else,并以某种方式将 0160804 替换为 ##MAXSIZE?问题基本上是如何从 64 的 MAXSIZE 到 0x%.016llX 中的 016?对于 MAXSIZE 的其他两种情况也是如此。

您可以使用标准 C _Generic 并删除大小参数。它使用 compile-time 类型检查,因此它与标记粘贴一样高效,但类型安全且不那么混乱:

#include <inttypes.h>
#include <stdio.h>

#define PRINT_Q(n) printf(  _Generic((n),                 \
                              int64_t: " 0x%.016" PRIX64, \
                              int32_t: " 0x%.08"  PRIX32, \
                              int16_t: " 0x%.04"  PRIX16  \
                            ), (n) )

int main (void)
{
  int64_t q64 = 0x1234567890ABCDEF;
  int32_t q32 = 0x12345678;
  int16_t q16 = 0x1234;

  PRINT_Q(q64);
  PRINT_Q(q32);
  PRINT_Q(q16);
}

输出:

 0x1234567890ABCDEF 0x12345678 0x1234

(但请注意,%X%PRIXnn 格式说明符需要一个无符号类型作为参数。考虑为无符号类型实现它。)