Теперь у меня есть структура, выглядящая так:
struct Struct {
uint8_t val1 : 2;
uint8_t val2 : 2;
uint8_t val3 : 2;
uint8_t val4 : 2;
} __attribute__((packed));
Есть ли способ сделать все val
единственным массивом? Точка не занимает пространство, а местоположение всех значений: мне нужно, чтобы они были в памяти без заполнения, и каждый из них занимал 2 бита. Не важно иметь массив, любая другая структура данных с простым доступом по индексу будет в порядке, и не имеет значения, является ли это простой C или C++. Производительность чтения/записи важна - она должна быть такой же (аналогичной), как и простые битовые операции, которые теперь используются для индексированного доступа.
Обновить:
То, что я хочу, точно можно описать как
struct Struct {
uint8_t val[4] : 2;
} __attribute__((packed));
Нет, C поддерживает только битовые поля в качестве составных элементов, и вы не можете иметь массивы из них. Я не думаю, что вы можете сделать:
struct twobit {
uint8_t val : 2;
} __attribute__((packed));
а затем выполните:
struct twobit array[32];
и ожидать, что array
будет состоять из 32 двухбитовых целых чисел, т.е. 8 байтов. Я думаю, что один char
в памяти не может содержать части разных struct
. У меня теперь нет абзаца и стиха.
Вам придется делать это самостоятельно, обычно используя макросы и/или встроенные функции для индексирования.
Вы должны вручную сделать бит материал, который происходит прямо сейчас:
constexpr uint8_t get_mask(const uint8_t n)
{
return ~(((uint8_t)0x3)<<(2*n));
}
struct Struct2
{
uint8_t val;
inline void set_val(uint8_t v,uint8_t n)
{
val = (val&get_mask(n))|(v<<(2*n));
}
inline uint8_t get_val(uint8_t n)
{
return (val&~get_mask(n))>>(2*n);
}
//note, return type only, assignment WONT work.
inline uint8_t operator[](uint8_t n)
{
return get_val(n);
}
};
Обратите внимание, что вы можете повысить производительность, если используете реальные команды сборки.
Также обратите внимание, что (почти) независимо от того, что uint8_t [4] будет иметь лучшую производительность, чем это, а тип с выравниванием процессора (uint32_t) может иметь даже лучшую производительность.