This repository has been archived on 2017-04-03. You can view files and clone it, but cannot push or open issues/pull-requests.
blog_post_tests/20131105225438.blog

49 lines
2.1 KiB
Plaintext

Finally, one-line endianness detection in the C preprocessor
<p>In 30 years of C programming, I thought I&#8217;d seen everything. Well, every bizarre trick you could pull with the C preprocessor, anyway. I was <a href="http://stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine">wrong</a>. Contemplate this:</p>
<pre language="C">
#include &lt;stdint .h&gt;
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
</pre>
<p>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:</p>
<p><span id="more-5095"></span></p>
<ul>
<li>Actually portable (well, assuming you have C99 stdint.h, which is a pretty safe assumption in 2013).</li>
<li>Doesn't require runtime code.</li>
<li>Doesn't allocate storage, not even constant storage.</li>
<li>One line, no auxiliary definitions required.</li>
<li>Readily comprehensible by inspection.</li>
</ul>
<p>Every previous endianness detector I've seen failed one or more of these tests and annoyed me in so doing.</p>
<p>In GPSD it's replacing this mess:</p>
<pre language="C">
/*
__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 &lt;sys/endian.h&gt;
#else
#include &lt;endian.h&gt;
#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__ */
</pre>
<p>And that, my friends, is progress.</p>
<p>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&#8217;s still pretty neat, though.</p>