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 3
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????
template
void SwapEnd(T& var)
{
static_assert(std::is_pod::value, "Type must be POD type for safety");
std::array varArray;
std::memcpy(varArray.data(), &var, sizeof(T));
for(int i = 0; i < static_cast(sizeof(var)/2); i++)
std::swap(varArray[sizeof(var) - 1 - i],varArray[i]);
std::memcpy(&var, varArray.data(), sizeof(T));
}
It's the magic power of C and C++ together! Simply swap the original variable character by character.
Point 1: No operators: 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.
Point 2: Be aware of alignment issues: Notice that we're copying to and from an array, which is the right thing to do because the C++ compiler doesn't guarantee that we can access unaligned memory (this answer was updated from its original form for this). For example, if you allocate uint64_t
, your compiler cannot guarantee that you can access the 3rd byte of that as a uint8_t
. Therefore, the right thing to do is to copy this to a char array, swap it, then copy it back (so no reinterpret_cast
). Notice that compilers are mostly smart enough to convert what you did back to a reinterpret_cast
if they're capable of accessing individual bytes regardless of alignment.
To use this function:
double x = 5;
SwapEnd(x);
and now x
is different in endianness.