[英]bit fields vs. stdint definitions
因此,我使用C ++進行編程,據我所知,沒有與stdint.h等效的C ++。 沒問題,因為您可以僅獲取stdint的副本並將其包括在內...但是我的問題基本上是這樣,
這兩段代碼有什么區別:
struct FREQ{
unsigned int FREQLOHI :16;
//etc...
};
和
struct FREQ{
uint16_t FREQLOHI;
//etc...
}
除了位域的明顯限制之外,還有性能/可移植性問題嗎? 哪個是首選?
不同之處在於在不同平台上unsigned int
的大小可能不同,而uint16_t保證具有16位寬度。 這意味着第一個(位域)結構的實例在不同平台上可能具有不同的大小。 而且,位域訪問更昂貴,因為它涉及額外的移位和掩碼。
例如,在unsigned int為32位寬的筆記本電腦上,第一個結構為32位寬,而第二個結構為16位。
當涉及到可移植性時,位域的情況要干凈得多,因為它是C ++中的一項古老的C語言功能,該功能在1998年被標准化時已包含在C ++中(ISO / IEC 14882:1998)。 另一方面, stdint.h
僅在1999年(ISO / IEC 9899:1999標准)添加到C中,因此不屬於C ++ 98(ISO / IEC 14882:1998)。 然后將相應的頭文件cstdint
合並到C ++ TR1中,但是它將所有標識符放在std::tr1
命名空間中。 Boost還提供了標題。 最新的C ++標准(於2011年9月發布的C ++ 11,又名ISO / IEC 14882:2011)包括標頭cstdint
,並將所有標識符放入std
名稱空間。 盡管如此, cstdint
得到了廣泛支持。
編譯器通常傾向於將單個位字段打包在一起,從而減小結構的整體大小。 這種打包的代價是訪問位域成員的速度較慢。 例如:
struct Bitfields
{
unsigned int eight_bit : 8;
unsigned int sixteen_bit : 16;
unsigned int eight_bit_2 : 8;
};
可能打包為
0 8 24
-----------------------------------------------------
| eight_bit | sixteen_bit | eight_bit_2 |
-----------------------------------------------------
每次您訪問sixteen_bit
都會產生移位和按位與運算。
另一方面,如果您這樣做
struct NonBitfields
{
uint8_t eight_bit;
uint16_t sixteen_bit;
uint8_t eight_bit_2;
};
然后,編譯器通常將成員對齊到單詞邊界處,並將其布局如下:
0 8 16 24
-----------------------------------------------------
| eight_bit | | sixteen_bit |
-----------------------------------------------------
| eight_bit_2| |
-----------------------------------------------------
與位域相比,這浪費了更多空間,但是可以更快地訪問成員而無需移位和屏蔽。
以下是其他一些區別:
sizeof
應用於位域成員。 在可移植性方面,兩個選項都應在任何符合標准的編譯器上工作。 如果在將結構寫出到文件或套接字時是指在不同平台之間的二進制可移植性,則無論哪種情況,所有押注都是無效的。
在偏好方面,除非有充分的理由將字段打包在一起以節省空間,否則我會選擇使用uint16_t
代替位字段。 如果結構中有很多bool
,則通常將使用位域將這些布爾標志一起壓縮到同一單詞中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.