C Fixed-Width Integers

Fixed-Width Integers in C: <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.


1. Exact-Width Integer Types

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.

Using Exact-Width Integers

#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; }


2. Fast and Least Integer Types

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.


3. Printing Fixed-Width Integers (<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).

Printing Using inttypes Macros

#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; }


Exercise

?

Which header file must be included to use the int32_t data type?