[英]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.