Указание размера в битах элементов массива в структуре

Теперь у меня есть структура, похожая на это:

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));

0

Решение

Нет, C поддерживает только битовые поля в качестве элементов структуры, и вы не можете иметь их массивы. Я не думаю, что вы можете сделать:

struct twobit {
uint8_t val : 2;
} __attribute__((packed));

а затем сделать:

struct twobit array[32];

и ожидать array состоять из 32 2-битных целых чисел, то есть 8 байтов. Один char в памяти не может содержать части разных structс, я думаю. У меня сейчас нет параграфа и стиха под рукой.

Вам придется сделать это самостоятельно, обычно используя макросы и / или встроенные функции для индексирования.

1

Другие решения

Вы должны вручную сделать кое-что, что происходит прямо сейчас:

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) может иметь даже лучшую производительность.

0

По вопросам рекламы [email protected]