簡體   English   中英

是否有理由避免使用位域結構成員?

[英]Are there reasons to avoid bit-field structure members?

我早就知道C中有位字段,偶爾我會用它們來定義密集的結構:

typedef struct Message_s {
     unsigned int flag : 1;
     unsigned int channel : 4;
     unsigned int signal : 11;
} Message;

當我閱讀開源代碼時,我經常會發現位掩碼和位移操作,以便在手工滾動的位域中存儲和檢索這些信息。 這是如此常見,我不認為作者不知道位字段語法,所以我想知道是否有理由通過位掩碼滾動位字段並轉移自己的操作而不是依靠編譯器生成用於獲取和設置此類位字段的代碼。

為什么其他程序員使用手工編碼的位操作而不是位域來將多個字段打包成一個字?

這個答案是基於意見的,因為這個問題非常開放:

  • 許多程序員不知道位域的可用性或不確定它們的可移植性和精確的語義。 有些人甚至不信任編譯器生成正確代碼的能力。 他們更喜歡編寫他們理解的顯式代碼。

    正如Cornstalks評論的那樣,這種態度植根於本文所解釋的現實生活體驗。

  • Bitfield的實際存儲器布局是實現定義的:如果存儲器布局必須遵循精確的規范,則不應使用位域,並且可能需要手動編碼的位操作。
  • 在簽名類型的位域中處理簽名值是實現定義的。 如果將有符號值打包到一系列位中,則對訪問函數進行手動編碼可能更可靠。

是否有理由避免使用位域結構?

bitfield-structs有一些限制:

  1. 位字段導致不可移植的代碼。 此外,位字段長度對字大小具有高依賴性。
  2. 由於不可尋址,因此無法讀取(使用scanf() )並在位字段上使用指針。
  3. 位字段用於將更多變量打包到較小的數據空間中,但會使編譯器生成其他代碼來操作這些變量。 這導致空間和時間復雜性的增加。
  4. sizeof()運算符不能應用於位字段,因為sizeof()以字節而不是以位為單位產生結果。

資源

所以你是否應該使用它們取決於。 閱讀更多內容為什么bit endianness是bitfields中的一個問題?


PS: 何時在C中使用位域?

沒有理由。 位域是有用和方便的。 它們在嵌入式項目中很常見。 某些架構(如ARM)甚至有特殊的指令來操作位域。

只需比較代碼(並編寫函數foo1的其余部分) https://godbolt.org/g/72b3vY

在許多情況下,能夠對一個字內的各個位組進行尋址,或者將一個字作為一個單元進行操作是很有用的。 該標准目前沒有提供任何實用和便攜的方式來實現這種功能。 如果編寫代碼以使用位域,並且稍后有必要將多個組作為一個單詞進行訪問,那么在沒有使用位字段重新編寫所有代碼或禁用基於類型的別名優化(使用類型雙關)的情況下,沒有很好的方法來適應這種情況。並希望一切都按預期布局。

使用移位和掩碼可能是不優雅的,但是直到C提供了將一個左值內的明確指定的位序列視為另一個左值的方法,它通常是確保代碼適應以滿足需要的最佳方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM