In a C application (not C++) I have a byte array of data received over the network. The array is 9 bytes long. The bytes 1 to 8 (zero-based) represent a 64-bit integer value as little endian. My CPU also uses little endian.
How can I convert these bytes from the array to an integer number?
I've tried this:
uint8_t rx_buffer[2000];
//recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, ...)
int64_t sender_time_us = *(rx_buffer + 1);
But it gives me values like 89, 219, 234 or 27. The sender sees the values as 1647719702937548, 1647719733002117 or 1647719743790424. (These examples don't match, they're just random samples.)
Unsafe solution:
int64_t sender_time_us = *(int64_t*)(rx_buffer + 1);
This is potentially an alignment violation, and it's a strict aliasing rule violation. It's undefined behaviour. On some machines, this can kill your program with a bus error.
Safe solution:
int64_t sender_time_us;
memcpy( &sender_time_us, rx_buffer + 1, sizeof( int64_t ) );
@Nate Eldredge points out that while this solution may look inefficient, a decent compiler should optimize this into something efficient. The net effect will be (a) to force the compiler to properly handle the unaligned access, if the target needs any special handling, (b) to make the compiler properly understand the aliasing and prevent any optimizations that would break it. For a target that is able to handle unaligned accesses normally, the generated code may not change at all.