我一直在閱讀關於C中的位字段,C標準如何不強制機器字中字段的任何特定排序,等等。這個位域會以我期望的方式工作嗎?
我希望這個問題適合SO的格式。
我的問題是我的結構(定義如下)是否會按我期望的方式執行。這是我想出了定義,然後我將討論什麼,我想:
typedef enum {
STATE_ONE,
STATE_TWO,
STATE_THREE,
STATE_FOUR
} __attribute__ ((packed)) State;
typedef struct MyStruct {
// One of State enum (maximum of 4 states).
unsigned state : 2;
// Remaining 30 bits are used differently depending on 'state'.
union {
// If 'state' is STATE_ONE (0), the remaining bits are an ID number.
unsigned id : 30;
/*
* For all other states, the remaining bits are the 2-tuple:
* (buffer A index, buffer B index).
*/
struct {
unsigned bufferAIdx : 16;
unsigned bufferBIdx : 14;
} __attribute__ ((packed)) index;
} __attribute__ ((packed));
} __attribute__ ((packed)) MyStruct;
(這是GCC,因此__attribute__
指令)。
你也許可以告訴我要去做什麼:根據「狀態」字段的值,我想用剩下的30位來達到不同的目的。它們應該是一個ID號碼,或者是指向不同緩衝區的2元組索引。 而且,MyStruct的每個實例最多可以放入5個字節。
所以我希望能夠做的是什麼這個效果:
MyStruct a, b;
a.state = STATE_ONE;
a.id = 123456;
b.state = STATE_THREE;
b.index.bufferAIdx = 6;
b.index.bufferBIdx = 2;
主要是我要找的輸入這是否是「正確的事」的事。換句話說,我在這裏濫用bitfields/union的想法嗎?如果你要成爲這個代碼的維護者,你會在看到這些時恐懼嗎?或者,您是否希望將整個數據對象存儲在uint32_t
類型中,並通過掩碼和切換進行操作?
只是出於好奇,爲什麼你關心它是否適合在32位?你打算擁有數以億計的這些? – Nemo
@Nemo:是的,會有很多這樣的。我相信對於其中一種情況,我們需要在內存中保存約3300萬個(並且內存不是無限的)。但是,根據Didier Trosset已經給出的答案,我可以放寬限制到5個字節,而不是4個字節。 –
請注意,通過使用5字節的結構,並在多於一個字節(使用14,16或30位的字節)上使用打包值,您可能會受到懲罰,將存儲器從32位移動到32位寄存器對齊的內存地址。它不是*只是一個字節的問題。 –