# inttypes.h **`inttypes.h`** solves a portability trap that bites you the first time you try to `printf` a `uint64_t`. On one platform `uint64_t` is `unsigned long`, so `%lu` works. On another it is `unsigned long long`, so you need `%llu`. Get it wrong and you get a compiler warning on one platform and silently wrong output on another. The format macros in this header expand to whichever specifier is correct for the current platform. ```c #include #include uint64_t bytes = 1099511627776ULL; // 1 TiB printf("%" PRIu64 " bytes\n", bytes); // always correct printf("%" PRIx64 " hex\n", bytes); // lowercase hex printf("%" PRIX64 " HEX\n", bytes); // uppercase hex ``` The naming pattern: `PRI` for `printf`, `SCN` for `scanf`; then the conversion letter (`d`, `i`, `u`, `x`, `X`, `o`); then the bit width. The full set covers 8, 16, 32, 64, and the `FAST`/`LEAST` variants from ``: ```c uint32_t id; scanf("%" SCNu32, &id); ``` The header also declares `strtoimax` and `strtoumax` for converting strings to `intmax_t`/`uintmax_t`, and `imaxabs`/`imaxdiv` for arithmetic on those types. The portable workaround without these macros — casting everything to `unsigned long long` and using `%llu` — works in practice today but generates warnings and will break if you move the code to a platform with a different `long long` size. The macros are the correct solution. ## Practice ```c // compile: gcc -o intdemo intdemo.c // run: ./intdemo // description: print fixed-width integers portably using PRI macros #include #include int main(void) { uint8_t a = 255; uint32_t b = 0xDEADBEEF; uint64_t c = UINT64_MAX; int64_t d = INT64_MIN; printf("uint8: %" PRIu8 "\n", a); printf("uint32: %" PRIu32 " (0x%" PRIx32 ")\n", b, b); printf("uint64: %" PRIu64 "\n", c); printf("int64: %" PRId64 "\n", d); return 0; } ``` Compile this on a 32-bit cross-compilation target and the output will be identical to a 64-bit build because the macros automatically expand to the right specifier. Try replacing `PRIu64` with `%lu` and compile for both targets — you will get a warning on at least one. That warning is the bug the macros fix.