# stdint.h Write `int` assuming it is 32 bits, run the code on a 16-bit microcontroller, and things break silently. **`stdint.h`** (C99) solves this by providing integer types with guaranteed widths, so you can write code that means exactly what it says regardless of platform. The main type families: ```c #include // exact width — guaranteed to be exactly N bits int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t // fast — at least N bits, chosen for speed on the platform int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t // least — smallest type with at least N bits int_least8_t int_least16_t int_least32_t int_least64_t uint_least8_t uint_least16_t uint_least32_t uint_least64_t // widest available integer type intmax_t uintmax_t // types wide enough to hold a pointer intptr_t uintptr_t ``` Corresponding limit macros: `INT8_MIN`, `INT8_MAX`, `UINT8_MAX`, `INT64_MIN`, `INT64_MAX`, `UINT64_MAX`, and so on. Constant macros suffix the literal to the correct type: ```c uint32_t mask = UINT32_C(0xDEADBEEF); int64_t big = INT64_C(-9000000000); ``` `intptr_t` and `uintptr_t` are wide enough to hold a pointer cast to an integer, which is useful for pointer tagging (storing flags in the low bits), hardware register addresses, and any place where you genuinely need to do arithmetic on a pointer value. The exact-width types (`int32_t`, etc.) may not exist on platforms where no native type has exactly that width — they are optional. The least-width types are always present. ## Practice ```c // compile: gcc -o inttest inttest.c // run: ./inttest // description: print sizes of standard integer types on this platform #include #include int main(void) { printf("int8_t = %zu bytes\n", sizeof(int8_t)); printf("int16_t = %zu bytes\n", sizeof(int16_t)); printf("int32_t = %zu bytes\n", sizeof(int32_t)); printf("int64_t = %zu bytes\n", sizeof(int64_t)); printf("intptr_t = %zu bytes\n", sizeof(intptr_t)); printf("INT32_MAX = %d\n", INT32_MAX); printf("UINT64_MAX = %llu\n", (unsigned long long)UINT64_MAX); return 0; } ``` On a 64-bit Linux system you will see `intptr_t` as 8 bytes (matching the pointer width). On a 32-bit build (`gcc -m32`) it becomes 4. The exact-width types stay the same size on both, which is exactly the point.