2014-02-10 3 views
0

Теперь у меня есть структура вида:Определение размера битых элементов массива в структурах

struct Struct { 
    uint8_t val1 : 2; 
    uint8_t val2 : 2; 
    uint8_t val3 : 2; 
    uint8_t val4 : 2; 
} __attribute__((packed)); 

Есть ли способ, чтобы сделать все val S один массивом? Точка не занимает пространство, а местоположение всех значений: мне нужно, чтобы они были в памяти без заполнения, и каждый из них занимал 2 бита. Не важно иметь массив, любая другая структура данных с простым доступом по индексу будет в порядке, и не имеет значения, является ли это просто C или C++. Производительность чтения/записи важна - она ​​должна быть такой же (аналогичной), как и простые битовые операции, которые теперь используются для индексированного доступа.

Update:

То, что я хочу точно можно охарактеризовать как

struct Struct { 
    uint8_t val[4] : 2; 
} __attribute__((packed)); 
+0

Я удалил свой ответ (массив структур), потому что он не соответствовал одному из ваших основных критериев: важна производительность записи/записи - она ​​должна быть такой же (похожей на), как и простые битовые операции, которые теперь используются для индексированного доступа_ Массив структуры не обеспечивал бы смежных мест памяти для элементов массива этой структуры, что ухудшало бы производительность чтения/записи. До сих пор я полагаю, что MadScienceDreams (хотя странный прозвище :) предложил концепцию, наиболее точно соответствующую вашей заявленной цели. – ryyker

ответ

1

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

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

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

struct twobit array[32]; 

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

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

+0

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

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

Смежные вопросы