<stdint.h>In standard C, the exact size (in bits) of fundamental integer types like int, long, and short is not strictly defined by the language standard.
For example, the standard only guarantees that an int is at least 16 bits. On older systems or microcontrollers, an int might be exactly 16 bits (capable of storing up to 32,767). However, on modern 64-bit desktop processors, an int is typically 32 bits.
This variability causes significant issues when writing cross-platform applications, working with specific file formats, or doing low-level network programming where you need exact data sizes. To solve this, C99 introduced the <stdint.h> library.
By including <stdint.h>, you gain access to new data types that specify their exact bit-width and whether they are signed or unsigned. These types guarantee the exact same size regardless of the operating system or architecture.
int8_t: Exact 8-bit signed integer.uint8_t: Exact 8-bit unsigned integer (often used to represent raw bytes).int16_t: Exact 16-bit signed integer.uint16_t: Exact 16-bit unsigned integer.int32_t: Exact 32-bit signed integer.uint32_t: Exact 32-bit unsigned integer.int64_t: Exact 64-bit signed integer.uint64_t: Exact 64-bit unsigned integer.#include <stdio.h> #include <stdint.h>int main() { int32_t balance = -50000; uint8_t rgb_color_red = 255; // Perfect for a byte of data printf("Size of int32_t: %zu bytes\n", sizeof(balance)); // Outputs 4 bytes (32 bits) printf("Size of uint8_t: %zu byte\n", sizeof(rgb_color_red)); // Outputs 1 byte (8 bits) return 0; }
Sometimes you don't need exactly a specific width, but you need at least that width, and you want the system to choose the fastest representation available.
int_least16_t, etc.): Guarantees the type is at least N bits wide. Useful when memory is extremely constrained but exact size doesn't strictly matter.int_fast32_t, etc.): Guarantees at least N bits, but the compiler will choose a larger size if it makes processor calculations faster. For example, int_fast16_t might actually be 32 bits on a 32-bit system because the CPU processes 32-bit blocks faster than 16-bit blocks.<inttypes.h>)Because standard printf format specifiers (like %d or %ld) depend on the variable standard types, they are not guaranteed to work correctly across platforms with fixed-width integers.
To safely print fixed-width integers, you must include the <inttypes.h> header, which provides special string macros (like PRId32 or PRIu64).
#include <stdio.h> #include <stdint.h> #include <inttypes.h>int main() { int32_t id = 123456; uint64_t huge_number = 18446744073709551615ULL; // PRId32 expands to the correct format specifier for a signed 32-bit int printf("ID: %" PRId32 "\n", id); // PRIu64 expands to the correct format specifier for an unsigned 64-bit int printf("Huge Number: %" PRIu64 "\n", huge_number); return 0; }
Which header file must be included to use the int32_t data type?