All the examples I've seen of reading a double of known endianness from a buffer to the platform endianness involve detecting the current platform's endianess and performing byte-swapping when necessary.
On the other hand, I've seen another way of doing the same thing except for integers that uses bit shifting (one such example).
This got me thinking that it might be possible to use a union and the bitshift technique to read doubles (and floats) from buffers, and a quick test implementation seemed to work (at least with clang on x86_64):
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
double read_double(char * buffer, bool le) {
union {
double d;
uint64_t i;
} data;
data.i = 0;
int off = le ? 0 : 7;
int add = le ? 1 : -1;
for (int i = 0; i < 8; i++) {
data.i |= ((uint64_t)(buffer[off] & 0xFF) << (i * 8));
off += add;
}
return data.d;
}
int main() {
char buffer_le[] = {0x6E, 0x86, 0x1B, 0xF0, 0xF9, 0x21, 0x09, 0x40};
printf("%f\n", read_double(buffer_le, true)); // 3.141590
char buffer_be[] = {0x40, 0x09, 0x21, 0xF9, 0xF0, 0x1B, 0x86, 0x6E};
printf("%f\n", read_double(buffer_be, false)); // 3.141590
return 0;
}
My question though is, is this a safe way to do this? Or is there undefined behavior involved here? Or if both this and the byte-swap method involve undefined behavior, is one safer than the other?