How do I convert between big-endian and little-endian values in C++?
EDIT: For clarity, I have to translate binary data (double-precision floating point values and 32-bit and 64-bit integers) from one CPU architecture to another. This doesn't involve networking, so ntoh() and similar functions won't work here.
EDIT #2: The answer I accepted applies directly to compilers I'm targetting (which is why I chose it). However, there are other very good, more portable answers here.
Portable technique for implementing optimizer-friendly unaligned non-inplace endian accessors. They work on every compiler, every boundary alignment and every byte ordering. These unaligned routines are supplemented, or mooted, depending on native endian and alignment. Partial listing but you get the idea. BO* are constant values based on native byte ordering.
These typedefs have the benefit of raising compiler errors if not used with accessors, thus mitigating forgotten accessor bugs.
We've done this with templates. You could so something like this:
Seriously... I don't understand why all solutions are that complicated! How about the simplest, most general template function that swaps any type of any size under any circumstances in any operating system????
It's the magic power of C and C++ together! Simply swap the original variable character by character.
Remember that I didn't use the simple assignment operator "=" because some objects will be messed up when the endianness is flipped and the copy constructor (or assignment operator) won't work. Therefore, it's more reliable to copy them char by char.
To call it, just use
and now
x
is different in endianness.Here's a generalized version I came up with off the top of my head, for swapping a value in place. The other suggestions would be better if performance is a problem.
Disclaimer: I haven't tried to compile this or test it yet.
i like this one, just for style :-)
On most POSIX systems (through it's not in the POSIX standard) there is the endian.h, which can be used to determine what encoding your system uses. From there it's something like this:
This swaps the order (from big-endian to little endian):
If you have the number 0xDEADBEEF (on a little endian system stored as 0xEFBEADDE), ptr[0] will be 0xEF, ptr[1] is 0xBE, etc.
But if you want to use it for networking, then htons, htonl and htonll (and their inverse ntohs, ntohl and ntohll) will be helpfull to converting from host order to network order.