In 30 years of C programming, I thought I’d seen everything. Well, every bizarre trick you could pull with the C preprocessor, anyway. I was wrong. Contemplate this:
#include <stdint .h> #define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
That is magnificently awful. Or awfully magnificent, I'm not sure which. And it pulls off a combination of qualities I've never seen before:
- Actually portable (well, assuming you have C99 stdint.h, which is a pretty safe assumption in 2013).
- Doesn't require runtime code.
- Doesn't allocate storage, not even constant storage.
- One line, no auxiliary definitions required.
- Readily comprehensible by inspection.
Every previous endianness detector I've seen failed one or more of these tests and annoyed me in so doing.
In GPSD it's replacing this mess:
/* __BIG_ENDIAN__ and __LITTLE_ENDIAN__ are define in some gcc versions only, probably depending on the architecture. Try to use endian.h if the gcc way fails - endian.h also doesn not seem to be available on all platforms. */ #ifdef __BIG_ENDIAN__ #define WORDS_BIGENDIAN 1 #else /* __BIG_ENDIAN__ */ #ifdef __LITTLE_ENDIAN__ #undef WORDS_BIGENDIAN #else #ifdef BSD #include <sys/endian.h> #else #include <endian.h> #endif #if __BYTE_ORDER == __BIG_ENDIAN #define WORDS_BIGENDIAN 1 #elif __BYTE_ORDER == __LITTLE_ENDIAN #undef WORDS_BIGENDIAN #else #error "unable to determine endianess!" #endif /* __BYTE_ORDER */ #endif /* __LITTLE_ENDIAN__ */ #endif /* __BIG_ENDIAN__ */
And that, my friends, is progress.
UPDATE: I was wrong: I thought the preprocessor would do all these operations, but it turns out this macro does expand to a small anount of code. It’s still pretty neat, though.