Как указано выше, используйте приемы объединения.
Тем не менее, есть несколько проблем с теми, о которых говорилось выше, в особенности то, что доступ к невыровненной памяти общеизвестно медленен для большинства архитектур, и некоторые компиляторы даже не распознают такие постоянные предикаты, если только не выровнено слово.
Поскольку простой тест с порядком байтов скучен, здесь идет функция (шаблон), которая переворачивает ввод / вывод произвольного целого числа в соответствии с вашей спецификацией, независимо от архитектуры хоста.
#include <stdint.h>
#define BIG_ENDIAN 1
#define LITTLE_ENDIAN 0
template <typename T>
T endian(T w, uint32_t endian)
{
// this gets optimized out into if (endian == host_endian) return w;
union { uint64_t quad; uint32_t islittle; } t;
t.quad = 1;
if (t.islittle ^ endian) return w;
T r = 0;
// decent compilers will unroll this (gcc)
// or even convert straight into single bswap (clang)
for (int i = 0; i < sizeof(r); i++) {
r <<= 8;
r |= w & 0xff;
w >>= 8;
}
return r;
};
Использование:
Для преобразования из данного порядкового номера в хост используйте:
host = endian(source, endian_of_source)
Чтобы преобразовать порядковый номер узла в указанный, используйте:
output = endian(hostsource, endian_you_want_to_output)
Результирующий код работает так же быстро, как при написании сборки вручную на clang, на gcc он немного медленнее (развернутый &, <<, >>, | для каждого байта), но все еще приличный.