У меня есть следующие
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
Большое спасибо за любой совет,
uint32_t
от<stdint.h>
или<inttypes.h>
; если вы хотите использовать эти типы, вам следует перейти на C89. В качестве расширения вполне вероятно, что GCC действительно позволяет их использовать, но C89 не имел такой поддержки.size_t
'z', как в"%zu"
.uint32_t
, но его не хватаетsize_t
. Ответ @ u0b34a0f6ae включает оба.Ответы:
Похоже, вы ожидаете
size_t
того жеunsigned long
(возможно, 64 бита), хотя на самом делеunsigned int
(32 бита). Попробуйте использовать%zu
в обоих случаях.Хотя я не совсем уверен.
источник
int32_t
факт, что он находитсяint
на вашем компиляторе / платформе, не означает, что его может не бытьlong
на другом. То же самое дляsize_t
. Это на самом деле происходит из его пути и делать больше работы , чтобы обнаружить эту ошибку , так как портативность легкий, естественный контроль будет просто чтить ЬурейуЮ как компилятор делает.%lu
вместе с(unsigned long)k
всегда правильно.size_t
сложнее, поэтому он%zu
был добавлен в C99. Если вы не можете его использовать, относитесь к нему так же, какk
(long
это самый большой тип в C89,size_t
вряд ли он будет больше).Пытаться
z
Представляет собой целое число от длины же , какsize_t
и наPRIu32
макро, определенное в заголовке C99inttypes.h
, представляет беззнаковое 32-разрядное целое число.источник
printf( "%lu", (unsigned long )i )
. В противном случае позже вы получите кучу предупреждений по всему коду из-за изменения типа.uint32_t
так что на самом деле это код C99, и он должен быть скомпилирован как таковой.Все, что нужно, - это согласование спецификаторов формата и типов, и вы всегда можете выполнить приведение, чтобы это стало правдой.
long
не менее 32 бит, поэтому%lu
вместе с(unsigned long)k
всегда правильно:size_t
сложнее, поэтому он%zu
был добавлен в C99. Если вы не можете его использовать, относитесь к нему так же, какk
(long
это самый большой тип в C89,size_t
вряд ли он будет больше).Если вы не получите спецификаторы формата, соответствующие передаваемому типу, это
printf
будет эквивалентно чтению слишком большого или слишком малого объема памяти из массива. Пока вы используете явное приведение типов для сопоставления типов, это переносимо.источник
Если вы не хотите использовать макросы PRI *, другой подход к печати ЛЮБОГО целочисленного типа - приведение к
intmax_t
илиuintmax_t
и использование"%jd"
или%ju
, соответственно. Это особенно полезно для типов POSIX (или других ОС), для которых, например, не определены макросы PRI *off_t
.источник