спецификаторы формата printf для Perl типов API - PullRequest
3 голосов
/ 07 февраля 2020

Существуют ли макросы, которые предоставляют правильные printf форматные спецификаторы для IV, UV, STRLEN, Size_t и SSize_t? Ни один из них не указан в perlapi .


C предоставляет макросы для спецификаторов формата для типов, предоставляемых stdint.h, таких как uint32_t.

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

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

Есть ли что-то похожее на PRIu32 для IV, UV, STRLEN, Size_t и SSize_t?


Большая проблема я пытаюсь предложить исправление для следующих предупреждений компиляции, которые появляются при установке Sort :: Key в Ubuntu в Windows Подсистема для Linux:

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=]

Ответы [ 2 ]

5 голосов
/ 07 февраля 2020
  • Для UV существуют следующие макросы:

    • UVuf (десятичное число)
    • UVof (восьмеричное)
    • UVxf (l c hex)
    • UVXf (u c hex)
  • Для IV следующие существует макрос:

    • IVdf (десятичный)
  • Для NV существуют следующие макросы:

    • NVef ("%e -i sh")
    • NVff ("%f -i sh")
    • NVgf ("%g -i sh ")
  • Для Size_t и STRLEN используйте встроенный модификатор длины z. [1]

    • %zu (десятичное число)
    • %zo (восьмеричное)
    • %zx (l c hex)
    • %zX (u c hex)
  • Для SSize_t используйте встроенный модификатор длины z. [1]

    • %zd (десятичное число)

Например,

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

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

  1. Пока Size_t и SSize_t настраиваются, они никогда не отличаются nt из size_t и ssize_t на практике, а STRLEN - это typedef для Size_t.
3 голосов
/ 07 февраля 2020

Если Size_t совпадает с size_t, то %zu является правильным.

STRLEN вероятно, но не обязательно, совпадает с size_t.

Если SSize_t совпадает с ssize_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_t и uintmax_t определены в <stdint.h>.

Вы можете обойтись без преобразования в long или unsigned long и использования %ld или %lu, например, если вы знаете, что тип не шире, чем long или unsigned long.

...