位域結構體能節省一些記憶體空間,但是使用不當會產生race conditions,導致程式異常,下面簡要分析錯誤產生的原因和解決方案。
首先定義乙個簡單的bit field結構體。
+structbit_filed val;++
+int test_bitfield1(void)+
++int test_bitfield2(void
)+
然後反彙編
ffffffc0005421e8 :ffffffc0005421e8: f0000fa1 adrp x1, ffffffc000739000
<__hyp_idmap_text_end+0x4800>ffffffc0005421ec: f9426821 ldr x1, [x1,#
1232
]ffffffc0005421f0:
52800000 mov w0, #0x0
//#0
ffffffc0005421f4:
39400022
ldrb w2, [x1]
ffffffc0005421f8:
32000042 orr w2, w2, #0x1
ffffffc0005421fc:
39000022
strb w2, [x1]
ffffffc000542200: d65f03c0 ret
ffffffc000542204
:ffffffc000542204: f0000fa1 adrp x1, ffffffc000739000
<__hyp_idmap_text_end+0x4800>ffffffc000542208: f9426821 ldr x1, [x1,#
1232
]ffffffc00054220c:
52800000 mov w0, #0x0
//#0
ffffffc000542210:
39400022
ldrb w2, [x1]
ffffffc000542214: 321f0042 orr w2, w2, #
0x2ffffffc000542218:
39000022
strb w2, [x1]
ffffffc00054221c: d65f03c0 ret
可以看到,這種情況下最小訪存單元是乙個byte,在上面標黃的指令中會從記憶體讀取乙個副本,如果test_bitfield1在執行黃色指令後被test_bitfield2強行插入,test_bitfield2執行完畢後test_bitfield1繼續執行,
在這種情況下test_bitfield2所做的修改會被丟棄。
所以平時如果需要用到bit filed struct, 需要注意:
1. 不同位域變數是不是在乙個storage unit(可以通過反彙編檢視)裡面
2. 有沒有被併發訪問的可能。
use distinct non-bit-field members of a structure
結構體中的位域
位域 有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區...
結構體中的位域
位域 有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區...
結構體中的位域
結構體中的位域 位域有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾個不同的區域...