Спецификаторы формата printf для uint32_t и size_t

У меня есть следующее

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

Я получаю следующее предупреждение при компиляции:

format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’

Когда я запустил это с помощью шины, я получил следующее:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

Большое спасибо за любые советы,

6 ответов

Решение

Похоже, вы ожидаете size_t быть таким же, как unsigned long (возможно, 64 бит), когда это на самом деле unsigned int (32 бита). Попробуйте использовать %zu в обоих случаях.

Я не совсем уверен, хотя.

Пытаться

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

z представляет целое число длины, такое же как size_tи PRIu32 макрос, определенный в заголовке C99inttypes.h, представляет 32-разрядное целое число без знака.

Все, что нужно, - это то, что спецификаторы формата и типы совпадают, и вы всегда можете привести это к действию. long не менее 32 бит, так %lu вместе с (unsigned long)k всегда правильно:

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_t сложнее, поэтому %zu был добавлен в C99. Если вы не можете использовать это, то относитесь к этому так же, как k (long самый большой тип в C89, size_t вряд ли будет больше).

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

Если вы не получите правильные спецификаторы формата для передаваемого вами типа, то printf будет делать то же самое, что читать слишком много или слишком мало памяти из массива. Пока вы используете явное приведение типов для соответствия, оно переносимо.

Если вы не хотите использовать макросы PRI*, другой способ печати ЛЮБОГО целочисленного типа состоит в приведении к intmax_t или же uintmax_t и использовать "%jd" или же %juсоответственно. Это особенно полезно для типов POSIX (или других ОС), для которых, например, не определены макросы PRI*. off_t,

Как мне распечатать значение переменных uint32_t и uint16_t?

      #include <stdio.h>     // need at least one of these two
#include <inttypes.h>
int main (void) {
    uint32_t a=1234;
    uint16_t b=5678;
    printf("%" PRIu32 "\n",a);
    printf("%" PRIu16 "\n",b);
    return 0;
}

В аналогичном случае для "phys_size_t" требуется "% llu" (размер физической памяти, как при u-boot). Я обнаружил это после того, как "% zu" в printf вернул следующее предупреждение компилятора.

предупреждение: формат '% zu' ожидает аргумент типа 'size_t', но аргумент 2 имеет тип 'Phys_size_t {aka long long unsigned int}' [-Wformat =] printf ("ram_size = dram_size =%zu", dram_size);

Правильно для Phys_size_t:

      printf("dram_size = %llu\n", dram_size);
Другие вопросы по тегам