cstdint


Include file: <cstdint>

The <cstdint> header is part of the C++ Standard Library and provides a set of typedefs for fixed-width integer types. This header ensures that you have access to integer types with specific sizes, regardless of the underlying platform or compiler. It's particularly useful when you need precise control over the size of integer types, which is common in systems programming, embedded systems, and when working with binary file formats or network protocols.

Key Characteristics

Example 1: Basic Usage of Fixed-Width Integer Types

#include <cstdint>
#include <iostream>

int main() {
    int8_t small_int = 127;
    uint16_t unsigned_short = 65535;
    int32_t regular_int = -2147483648;
    uint64_t big_unsigned = 18446744073709551615ULL;

    std::cout << "int8_t: " << static_cast<int>(small_int) << std::endl;
    std::cout << "uint16_t: " << unsigned_short << std::endl;
    std::cout << "int32_t: " << regular_int << std::endl;
    std::cout << "uint64_t: " << big_unsigned << std::endl;

    return 0;
}

Explanation:

Example 2: Using Minimum-Width Types in a Portable Struct

#include <cstdint>
#include <iostream>

struct NetworkPacket {
    uint_least8_t type;
    uint_least16_t length;
    uint_least32_t sequence_number;
};

void print_packet(const NetworkPacket& packet) {
    std::cout << "Packet Type: " << static_cast<int>(packet.type) << std::endl;
    std::cout << "Packet Length: " << packet.length << std::endl;
    std::cout << "Sequence Number: " << packet.sequence_number << std::endl;
}

int main() {
    NetworkPacket packet = {5, 1024, 123456789};
    print_packet(packet);

    return 0;
}

Explanation:

Example 3: Utilizing Fast Types for Performance-Critical Operations

#include <cstdint>
#include <iostream>
#include <chrono>

uint_fast32_t fibonacci(uint_fast8_t n) {
    if (n <= 1) return n;
    uint_fast32_t a = 0, b = 1;
    for (uint_fast8_t i = 2; i <= n; ++i) {
        uint_fast32_t temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

int main() {
    const int iterations = 1000000;
    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < iterations; ++i) {
        fibonacci(30);
    }

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff = end - start;

    std::cout << "Time to calculate fibonacci 1,000,000 times: " << diff.count() << " s" << std::endl;

    return 0;
}

Explanation:

Example 4: Working with Integer Limits and Constant Macros

#include <cstdint>
#include <iostream>
#include <iomanip>

int main() {
    std::cout << "Integer Limits:" << std::endl;
    std::cout << "INT8_MIN: " << static_cast<int>(INT8_MIN) << std::endl;
    std::cout << "INT8_MAX: " << static_cast<int>(INT8_MAX) << std::endl;
    std::cout << "UINT8_MAX: " << static_cast<int>(UINT8_MAX) << std::endl;
    std::cout << "INT16_MIN: " << INT16_MIN << std::endl;
    std::cout << "INT16_MAX: " << INT16_MAX << std::endl;
    std::cout << "UINT16_MAX: " << UINT16_MAX << std::endl;
    std::cout << "INT32_MIN: " << INT32_MIN << std::endl;
    std::cout << "INT32_MAX: " << INT32_MAX << std::endl;
    std::cout << "UINT32_MAX: " << UINT32_MAX << std::endl;
    std::cout << "INT64_MIN: " << INT64_MIN << std::endl;
    std::cout << "INT64_MAX: " << INT64_MAX << std::endl;
    std::cout << "UINT64_MAX: " << UINT64_MAX << std::endl;

    std::cout << "\nConstant Macros:" << std::endl;
    std::cout << "INT8_C(127): " << static_cast<int>(INT8_C(127)) << std::endl;
    std::cout << "UINT16_C(65535): " << UINT16_C(65535) << std::endl;
    std::cout << "INT32_C(-2147483648): " << INT32_C(-2147483648) << std::endl;
    std::cout << "UINT64_C(18446744073709551615): " << UINT64_C(18446744073709551615) << std::endl;

    return 0;
}

Explanation:

Additional Considerations

  1. Portability: Using these fixed-width types ensures consistent behavior across different platforms and compilers.

  2. Performance: While fixed-width types guarantee size, they may not always be the most efficient on all platforms. Use fast types when performance is critical.

  3. Overflow Behavior: Be aware that overflow behavior is still undefined for signed types. Always check for potential overflows in your code.

  4. Printing: When printing 8-bit types, cast them to int to avoid them being treated as characters.

  5. Compatibility: These types are compatible with C, making them useful in C/C++ interop scenarios.

Summary

The <cstdint> header in C++ provides a set of portable integer types with guaranteed sizes:

These types are essential for writing portable code, especially in systems programming, embedded systems, and when dealing with binary data or network protocols. By using <cstdint>, developers can ensure consistent integer sizes across different platforms and compilers, leading to more robust and portable code.

Previous Page | Course Schedule | Course Content