2014-02-10 26 views
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(雖然是一個奇怪的綽號:)提供了最符合您的既定目標的概念。 – 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)的性能可能會更好。