NDK r8c
I tracked down a nasty bug in third party code, but I think it's actually the NDK's fault. I'm posting here so someone can confirm or deny it.
<machine/_types.h> gets indirectly included from a system header (for example, from
<csignal>) in one of my headers. At the bottom, there's this bit of code:
#ifdef __ARMEB__
#define _BYTE_ORDER _BIG_ENDIAN
#else
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif
Since __ARMEB__ is never defined, that code sets _BYTE_ORDER =
_LITTLE_ENDIAN. The only problem is that _LITTLE_ENDIAN does not exist
at this point, so it's defining _BYTE_ORDER to nothing! Not the same as #undef'ing it though (this is important later)
The third party library's "types" header detects endianness like this:
#if (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN))
#define SF_BYTE_ORDER SF_BIG_ENDIAN
#else
#define SF_BYTE_ORDER SF_LITTLE_ENDIAN
#endif
Seems pretty straight forward. I know that Android is little endian, so I was shocked to see SF_BIG_ENDIAN being defined *most* of the time. Huh?
Here's what I think is happening: Since _BYTE_ORDER is defined as nothing and _BIG_ENDIAN doesn't exist, the preprocessor considers them to be equal. I think technically it treats them both as 0, but I could be wrong.
My current workaround is to add -D_LITTLE_ENDIAN=1234 to my GCC flags. I got the idea by looking at how
<sys/endian.h> and
<linux/byteorder/little_endian.h> define _LITTLE_ENDIAN as 1234. I'm not sure it's the best method, but it works.
It seems wrong to me that
<machine/_types.h> uses _LITTLE_ENDIAN and _BIG_ENDIAN without defining them. It should check that they're defined, or even better, include a header that does define them.
Lastly, the correct endianness was *sometimes* detected by simply not including any system headers from a few CPP files. That way _BYTE_ORDER wasn't even defined, which caused the #else clause to evaluate in the third party header.