Я работаю над функцией, которая хранит 64-битное значение в памяти в формате большого конца. Я надеялся, что могу написать переносимый код C99, который работает как на небольших, так и на больших endian-платформах, а современные компиляторы x86 генерируют инструкцию bswap
автоматически без встроенных функций или встроенных функций, Поэтому я начал со следующей функции:
#include <stdint.h>
void
encode_bigend_u64(uint64_t value, void *vdest) {
uint64_t bigend;
uint8_t *bytes = (uint8_t*)&bigend;
bytes[0] = value >> 56;
bytes[1] = value >> 48;
bytes[2] = value >> 40;
bytes[3] = value >> 32;
bytes[4] = value >> 24;
bytes[5] = value >> 16;
bytes[6] = value >> 8;
bytes[7] = value;
uint64_t *dest = (uint64_t*)vdest;
*dest = bigend;
}
Это отлично работает для clang, который компилирует эту функцию:
bswapq %rdi
movq %rdi, (%rsi)
retq
Но GCC не может обнаружить байтовый обмен. Я попробовал несколько разных подходов, но они только ухудшили ситуацию. Я знаю, что GCC может обнаруживать байтовые свопы, используя побитовое - и, shift, и побитовое - или, но почему это не работает при написании байтов?
Изменить: Я нашел соответствующую ошибку GCC.