Many implementations of htonl()
or ntohl()
test for the endianness of the platform first and then return a function which is either a no-op or a byte-swap.
I once read a page on the web about a few tricks to handle to/from big/little-endian conversions, without any preconceived knowledge of the hardware configuration. Just taking endianness for what it is : a representation of integers in memory. But I could not find it again, so I wrote this :
typedef union {
uint8_t b[4];
uint32_t i;
} swap32_T;
uint32_t to_big_endian(uint32_t x) {
/* convert to big endian, whatever the endianness of the platform */
swap32_T y;
y.b[0] = (x & 0xFF000000) >> 24;
y.b[1] = (x & 0x00FF0000) >> 16;
y.b[2] = (x & 0x0000FF00) >> 8;
y.b[3] = (x & 0x000000FF);
return y.i;
}
My two questions are :
- Do you know a cleaner way to write this
to_big_endian()
function ? - Did you ever bookmarked this mysterious page I can not find, which contained very precious (because unusual) advices on endianness ?
edit
not really a duplicate (even if very close) mainly because I do not want to detect endianness. The same code compile on both architecture, with the same result
little endian
- for
u = 0x12345678
(stored as0x78 0x56 0x34 0x12
) to_big_endian(u) = 0x12345678
(stored as0x78 0x56 0x34 0x12
)
big endian
- for
u = 0x12345678
(stored as0x12 0x34 0x56 0x78
) to_big_endian(u) = 0x78563412
(stored as0x78 0x56 0x34 0x12
)
same code, same result... in memory.
_BIG_ENDIAN_
) and use that to determine whether your function should be a no-op or not. – Paul R