Detecting endianness programmatically in a C++ program
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"); }