Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting endianness programmatically in a C++ program

People also ask

How do you know if you have endianness?

If it is little-endian, it would be stored as “01 00 00 00”. The program checks the first byte by dereferencing the cptr pointer. If it equals to 0, it means the processor is big-endian(“00 00 00 01”), If it equals to 1, it means the processor is little-endian (“01 00 00 00”).

What is big-endian in C?

Big endian is implemented in PowerPC and most networking devices. The big endian byte order means, when the computer writes a word (Multi Byte) into memory, it begins by writing the highest byte to the lowest memory address and continues until it has written the lowest byte to the highest memory address.

How do you read big-endian?

Big endian machine: Stores data big-end first. When looking at multiple bytes, the first byte (lowest address) is the biggest. Little endian machine: Stores data little-end first. When looking at multiple bytes, the first byte is smallest.

Is my PC Little Endian?

If your PC is a (Windows-style) PC running Intel, it is little-endian. This code does assume a 32-bit int type (rather than 64-bit or 16-bit).


I don't like the method based on type punning - it will often be warned against by compiler. That's exactly what unions are for !

bool is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
}

The principle is equivalent to the type case as suggested by others, but this is clearer - and according to C99, is guaranteed to be correct. gcc prefers this compared to the direct pointer cast.

This is also much better than fixing the endianness at compile time - for OS which support multi-architecture (fat binary on Mac os x for example), this will work for both ppc/i386, whereas it is very easy to mess things up otherwise.


You can do it by setting an int and masking off bits, but probably the easiest way is just to use the built in network byte conversion ops (since network byte order is always big endian).

if ( htonl(47) == 47 ) {
  // Big endian
} else {
  // Little endian.
}

Bit fiddling could be faster, but this way is simple, straightforward and pretty impossible to mess up.


You can use std::endian if you have access to C++20 compiler such as GCC 8+ or Clang 7+.

Note: std::endian began in <type_traits> but was moved to <bit> at 2019 Cologne meeting. GCC 8, Clang 7, 8 and 9 have it in <type_traits> while GCC 9+ and Clang 10+ have it in <bit>.

#include <bit>

if constexpr (std::endian::native == std::endian::big)
{
    // Big endian system
}
else if constexpr (std::endian::native == std::endian::little)
{
    // Little endian system
}
else
{
    // Something else
}

Please see this article:

Here is some code to determine what is the type of your machine

int num = 1;
if(*(char *)&num == 1)
{
    printf("\nLittle-Endian\n");
}
else
{
    printf("Big-Endian\n");
}