Finally, one-line endianness detection in the C preprocessor
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
#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
#else
#include
#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.
Published on November 05, 2013 19:54
No comments have been added yet.
Eric S. Raymond's Blog
- Eric S. Raymond's profile
- 140 followers
Eric S. Raymond isn't a Goodreads Author
(yet),
but they
do have a blog,
so here are some recent posts imported from
their feed.
