Machine endian C++

Endianness determines the byte order in which multi-byte data types (e.g., int, float, double) are stored in memory.

  • Little Endian: Least significant byte (LSB) stored first (e.g., x86, x86-64).
  • Big Endian: Most significant byte (MSB) stored first (e.g., some older RISC processors, network protocols).

🔹 Method 1: Using Union (Portable & Efficient)

This method leverages a union to interpret the same memory as different data types.

#include <iostream>

bool isLittleEndian() {
    union {
        uint32_t i;
        char c[4];
    } test = {0x01020304};  // Stored as 04 03 02 01 in Little Endian

    return test.c[0] == 0x04;  // If LSB is at lowest address, it's Little Endian
}

int main() {
    if (isLittleEndian()) {
        std::cout << "Little Endian\n";
    } else {
        std::cout << "Big Endian\n";
    }
    return 0;
}

Output on most modern machines:

Little Endian

🔹 Method 2: Using Pointer Casting

A simple approach using pointer casting to inspect byte order.

#include <iostream>

bool isLittleEndian() {
    uint16_t num = 0x1;  
    char *bytePtr = reinterpret_cast<char*>(&num);
    return (*bytePtr == 1);  // LSB stored first → Little Endian
}

int main() {
    std::cout << (isLittleEndian() ? "Little Endian\n" : "Big Endian\n");
    return 0;
}


🔹 Method 3: Using htonl (Network Byte Order)

Networking typically uses Big Endian (Network Byte Order), so we can compare a number before and after conversion.

#include <iostream>
#include <arpa/inet.h>  // For htonl()

int main() {
    uint32_t num = 0x1;
    if (htonl(num) == num) {
        std::cout << "Big Endian\n";
    } else {
        std::cout << "Little Endian\n";
    }
    return 0;
}

🛑 Limitation: Requires <arpa/inet.h> (Unix/Linux), may not be portable.


🔹 Method 4: Using std::endian in C++20

C++20 introduces std::endian in <bit> for built-in endianness checks.

#include <iostream>
#include <bit>

int main() {
    if constexpr (std::endian::native == std::endian::little) {
        std::cout << "Little Endian\n";
    } else {
        std::cout << "Big Endian\n";
    }
    return 0;
}

Best for Modern C++ but requires C++20.


🛠 Which Method Should You Use?

MethodPortabilityPerformanceC++ Version
Union Trick✅ High⚡ Very FastC++98+
Pointer Casting✅ High⚡ Very FastC++98+
htonl() (Network Byte Order)⚠ Unix/Linux only⚡ FastC++98+
C++20 std::endian❌ C++20 only⚡ FastC++20+

🔹 Recommended: Use Union Trick or Pointer Casting for maximum portability.
🔹 Use C++20 std::endian if modern C++ features are available.