Если вы должны упаковать данные, то очевидная вещь - использовать специфические для реализации прагмы для упаковки структуры, избегая, таким образом, заполнения.Если вы не хотите этого делать (почему бы и нет?), Тогда можно сделать что-то вроде этого:
typedef uint8_t (*Thingy)[sizeof(uint32_t) + 1];
static inline uint32_t read_a(Thingy t) {
uint32_t val;
memcpy(&val, t, sizeof(uint32_t));
return val;
}
static inline void write_b(Thingy t, uint8_t val) {
reinterpret_cast<uint8_t*>(t)[sizeof(uint32_t)] = val;
}
И очевидное для write_a
и read_b
.
Запускиз этих четырех фрагментов вы можете сделать вещи более объектно-ориентированными в C ++ по своему вкусу.Я набрал Thingy
как указатель на массив, чтобы ++
и + n
делали то, что вы ожидали от итератора, но вы не можете просто присвоить *thingy
, как если бы вы использовали итератор,С таким же успехом можно написать класс, который содержит элемент данных uint8_t*
, перегрузить необходимые операторы для достижения того же результата, а затем читать и писать через функции-члены или, возможно, объекты-посредники.тот факт, что uint8_t
существует, подразумевает, что обязательно sizeof(uint32_t) == 4
.Так что если у вас есть какая-то константа из других источников, например #define PACKED_THINGY_SIZE 5
, вы можете использовать ее переносимо.