endian bug in <machine/_types.h> ?

102 views
Skip to first unread message

foo64

unread,
Jan 4, 2013, 7:48:46 PM1/4/13
to andro...@googlegroups.com
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.
Reply all
Reply to author
Forward
0 new messages