Endianness and you

Programming is all about generalizations. We, as programmers, usually do not want to worry about all the small details; We will usually assume that there’s enough physical memory on the machine, we will knowingly use cross-platform libraries to make the operating system we’re running on irrelevant as well, and sometimes we will even resort to using programming languages that take these ideas to the extreme – like i.e. Java, which runs entirely on a virtual machine — making all above issues non-existent.

But there comes a time, especially in low-level programming languages (like C++ luckily is), when we simply cannot ignore certain low level details. One such example is the expected, architecture specific, Endianness.

Quoting Wikipedia:

Endianness is the ordering of individually addressable sub-units (words, bytes, or even bits) within a longer data word stored in external memory.

To be more specific, usually what concerns us is the byte ordering (since every byte is individually addressable in the common x86/IA32 architecture) within a bigger word, such as a 32bit integer (4bytes). There are essentially two “core” options:

  • Little Endian — Little (less significant) byte first.
  • Big Endian — Big (most significant) byte first.

Little Endian, in my opinion, is the less intuitive one. It means that if we are to store a 32bit integer of the Hexadecimal value 0x10203040 in memory address a, then the memory footprint would look like this: [40 30 20 10], where a[0]=40 a[1]=30 a[2]=20 a[3]=10.

Most PCs are of the x86 architecture. As such, you are very likely to bump into the Little Endian storage it employs. Here is a simple program illustrating the situation:

#include <iostream>

int main () {
    int integer = 0x10203040;
    char *ptr   = static_cast<char*>(static_cast<void*>(&integer));

    std::cout << "int:   " << std::hex << integer 
        << std::endl;
    std::cout << "int[0]:" << std::hex << static_cast<int>(ptr[0]) 
        << std::endl;

    if (ptr[0] == (integer&0xff))
        std::cout << "little endian detected" << std::endl;
        std::cout << "big endian detected" << std::endl;

As expected, on my Intel Pentium M, the output would be:

antrikot:~/work/sandbox> ./endianness-test
int: 10203040
little endian detected

Leave a Reply

Your email address will not be published. Required fields are marked *