位欄位

按位運算有多貴?假設一個簡單的非位欄位結構:

struct foo {
    unsigned x;
    unsigned y;
}
static struct foo my_var;

在以後的一些程式碼中:

my_var.y = 5;

如果 sizeof (unsigned) == 4,則 x 儲存在結構的開頭,y 儲存在 4 個位元組中。生成的彙編程式碼可能類似於:

loada register1,#myvar     ; get the address of the structure
storei register1[4],#0x05  ; put the value '5' at offset 4, e.g., set y=5

這很簡單,因為 x 不與 y 混合。但想象一下用位域重新定義結構:

struct foo {
    unsigned x : 4; /* Range 0-0x0f, or 0 through 15 */
    unsigned y : 4;
}

xy 都將分配 4 位,共享一個位元組。結構因此佔用 1 個位元組而不是 8 個。考慮元件現在設定 y,假設它最終在高位半位元組中:

loada  register1,#myvar        ; get the address of the structure
loadb  register2,register1[0]  ; get the byte from memory
andb   register2,#0x0f         ; zero out y in the byte, leaving x alone
orb    register2,#0x50         ; put the 5 into the 'y' portion of the byte
stb    register1[0],register2  ; put the modified byte back into memory

如果我們有數千或數百萬個這樣的結構,這可能是一個很好的權衡,它有助於將記憶體保留在快取中或防止交換 - 或者可能使可執行檔案變得臃腫,從而惡化這些問題並減慢處理速度。和所有事情一樣,要善於判斷。

裝置驅動程式的使用: 避免使用位欄位作為裝置驅動程式的巧妙實現策略。位元欄位儲存佈局在編譯器之間不一定是一致的,使得這種實現不可移植。對設定值的讀取 - 修改 - 寫入可能無法執行裝置所期望的操作,從而導致意外行為。