Спецификаторы формата 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);