The program below makes assumptions about the packing of bit-fields, type punning and object representation. In other words, it makes no pretense at portability. Still, it has the advantage of being fast. Can this program be said to be correct with the limitation of requiring a supported compiler and a platform with the right endiness?
#include <cassert>
#include <cstdint>
union Data {
uint8_t raw[2];
struct __attribute__((packed)) {
unsigned int field1: 3, field2: 3, field3: 1, field4: 2;
unsigned int field5: 7;
} interpreted;
};
int main() {
static_assert(sizeof(Data) == 2, "Struct size incorrect");
static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__, "Only little-endian platform support is currently implemented");
static_assert(
#if defined(__GNUC__) || defined(__clang__)
true,
#else
false,
#endif
"Compiler is neither GCC nor Clang"
);
Data d{.raw{0x69, 0x01}};
/**
*
* 0x69 = 0b0110 1001, 0x01 = 0b0000 0001
* On a little endian platform, each byte will be laid out in memory in reverse order, that is
* [1001 0110, 1000 0000].
* The GCC and clang compilers lay out the struct members in the order they are defined, and each of the values will be interpreted in the reverse order (little-endian), so
* field1: 100 = 0b001
* field2: 101 = 0b101
* field3: 1 = 0b1
* field4: 01 = 0b10
* field5: 0000000 = 0
*
* Therefore, the following assertions will hold if the preceding assertions were satisfied.
*/
assert(d.interpreted.field1 == 1);
assert(d.interpreted.field2 == 5);
assert(d.interpreted.field3 == 1);
assert(d.interpreted.field4 == 2);
assert(d.interpreted.field5 == 0);
}