That test cannot work for a pre-processor if-directive.
The upcoming C++20 is proposed to have std::endian
. It can be used without the pre processor.
static_assert(std::endian::native == std::endian::big
|| std::endian::native == std::endian::little);
struct ABig {
char a:4;
char b:4;
};
struct ALit {
char b:4;
char a:4;
};
using A = std::conditional_t<std::endian::native == std::endian::big, ABig, ALit>;
Prior to C++20, there is no standard way of getting the endianness.
A portable solution is to use pre-defined macros to detect the system. Some systems are little endian (Windows), while others provide a header with macro definitions (<endian.h>
in Linux, <sys/endian.h>
in BSD and so on) and others may be different in some other way. The GCC compiler provides macros:
__BYTE_ORDER__
__ORDER_LITTLE_ENDIAN__
__ORDER_BIG_ENDIAN__
__ORDER_PDP_ENDIAN__
That said, pretty much every aspect of the representation of bit fields is implementation defined, and if it is important for the order to be exact - as it appears to be - then you're going to have to rely on particular implementation anyway, so portability is not achievable. Decide your target system and once you've decided, consult the documentation of that system for how to get the endianness.
It's best to not rely on the representation of bit fields.