Все, что нужно, - это согласование спецификаторов формата и типов, и вы всегда можете выполнить приведение, чтобы это стало правдой. 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будет эквивалентно чтению слишком большого или слишком малого объема памяти из массива. Пока вы используете явное приведение типов для сопоставления типов, это переносимо.
uint32_tот<stdint.h>или<inttypes.h>; если вы хотите использовать эти типы, вам следует перейти на C89. В качестве расширения вполне вероятно, что GCC действительно позволяет их использовать, но C89 не имел такой поддержки.