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

0

Теперь у меня есть структура, выглядящая так:

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
    Я удалил свой ответ (массив структур), потому что он не соответствовал одному из ваших основных критериев: производительность чтения / записи важна - она должна быть такой же (аналогичной), как и простые битовые операции, которые теперь используются для индексированного доступа . Массив Структура не обеспечит смежные области памяти для элементов массива этой структуры, что снизит производительность чтения / записи. До сих пор я считаю, что MadScienceDreams (хотя и странный псевдоним :) предложил концепцию, наиболее точно соответствующую вашей заявленной цели.
Теги:
arrays
struct
bit-packing

2 ответа

1
Лучший ответ

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

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

а затем выполните:

struct twobit array[32];

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

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

  • 0
    Я имею в виду не отдельный массив таких типов, а поле в структуре, где это поле является массивом.
0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню