Perl API 类型的 printf 格式说明符

printf format specifiers for Perl API types

是否有宏为 IVUVSTRLENSize_tSSize_t 提供正确的 printf 格式说明符? None 列在 perlapi.


C 为 stdint.h 提供的类型的格式说明符提供了宏,例如 uint32_t.

#include <inttypes.h>
#include <stdint.h>

uint32_t i = ...;
printf("i = %" PRIu32 "\n", i);

IVUVSTRLENSize_tSSize_t 是否有类似于 PRIu32 的内容?


larger problem 是我试图建议修复在 Windows 子系统 Ubuntu 上安装 Sort::Key 时产生的以下编译警告41=]:

Key.xs: In function ‘_keysort’:
Key.xs:237:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘IV {aka long int}’ [-Wformat=]
      croak("unsupported sort type %d", type);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~
Key.xs: In function ‘_multikeysort’:
Key.xs:547:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘STRLEN {aka long unsigned int}’ [-Wformat=]
   croak("wrong number of results returned "
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Key.xs:547:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘IV {aka long int}’ [-Wformat=]

如果Size_tsize_t相同,则%zu正确。

STRLEN 可能但不确定与 size_t.

相同

如果SSize_tssize_t相同,则%zd可能正确(这很复杂)。

对于其他类型,如果您不知道它们对应的预定义类型,请转换为已知类型。了解签名会有所帮助。例如:

some_unknown_signed_integer_type n = 42;
some_unknown_unsigned_integer_type x = 128;
printf("n = %jd\n", (intmax_t)n);
printf("x = %ju\n", (uintmax_t)x);

intmax_tuintmax_t 定义在 <stdint.h>.

您可以转换为 longunsigned long 并使用 %ld%lu,例如,如果您碰巧知道类型是 no比 longunsigned long.

  • 对于UV,存在以下宏:

    • UVuf(十进制)
    • UVof(八进制)
    • UVxf(lc 十六进制)
    • UVXf(uc 十六进制)
  • 对于IV,存在以下宏:

    • IVdf(十进制)
  • 对于NV,存在以下宏:

    • NVef(“%e-ish”)
    • NVff(“%f-ish”)
    • NVgf(“%g-ish”)
  • 对于Size_tSTRLEN,使用内置的z长度修饰符。[1]

    • %zu(十进制)
    • %zo(八进制)
    • %zx(lc 十六进制)
    • %zX(uc 十六进制)
  • 对于 SSize_t,使用内置的 z 长度修饰符。[1]

    • %zd(十进制)

例如,

IV iv      = ...;
STRLEN len = ...;

croak("iv=%" IVdf " len=%zu", iv, len);

  1. 虽然 Size_tSSize_t 是可配置的,但它们在实践中与 size_tssize_t 没有什么不同,并且 STRLEN 是一个类型定义Size_t.