3 ms·
Here is another solution for loading a potentially unaligned 64-bit integer in the CPU's byte order, that does not violate strict aliasing: uint64_t load64(u
by el_pollo_diablo 3y ago
Here is another solution for loading a potentially unaligned 64-bit integer in the CPU's byte order, that does not violate strict aliasing:
uint64_t load64(uint8_t const *b) {
union {
uint64_t u64;
uint8_t u8[8];
} u = {.u8 = {
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]
}};
return u.u64;
}
Type punning through a union is explicitly supported by the C standard, insofar as we do not evaluate uninitialized memory or trap representations. We are fine here, as uint64_t has no trap representations, and must have exactly the size of 8 uint8_ts, as those types have no padding bits.
GCC appears to compile this function to a plain unaligned load at optimization level 2, when supported, e.g. on arm64 (see https://godbolt.org/z/frEox67sG https://godbolt.org/z/frEox67sG).
- el_pollo_diablo 3y agoFurthermore, one advantage of this solution over using memcpy is that the compiler can still understand what it does (and aggressively optimize it) in a freestanding environment.