Endianness and you
September 30th, 2010 § Leave a Comment
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 0×10203040 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;
else
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
int[0]:40
little endian detected