C 和 C++ 中的位域:它们在哪里使用?

Posted

技术标签:

【中文标题】C 和 C++ 中的位域:它们在哪里使用?【英文标题】:Bit fields in C and C++: where are they used? 【发布时间】:2014-01-03 19:40:24 【问题描述】:

我使用 C 和 C++ 已经有一段时间了。

在学习基础知识的同时,您会遇到such interesting thing as bit fields。 在编程实践中位域的使用具有某种争议性。

这种低级功能的使用在哪些情况下提供了真正的好处,是否有正确使用位域的具体示例?

【问题讨论】:

尝试编写一个可变大小的列式数据库。 这有点宽泛。但是依赖于平台的低级序列化可以从位字段中受益,大型内存数据结构、缓存友好的内存绑定工作等也可以。 @JamesKanze “以平台相关的方式”这句话很重要:标准未指定的布局并不意味着您的编译器未指定,许多编译器确实以很好的打包方式布局它们并且是稳定的在编译器的迭代之间。 @Yakk 一些编译器(我想)确实记录了这一点,但这确实将您与特定的编译器联系起来。大多数编译器都没有。 (我在使用过的任何编译器中都没有找到这样的文档。) @JamesKanze:ISO/IEC C 标准要求记录此类实现细节。例如参见ARM's documentation。如果您的编译器没有记录这一点,那么就不能说它真正符合 ISO 标准。 【参考方案1】:

在使用嵌入式系统和微控制器时,寄存器中的各个位可能与处理器设置或输入/输出相关联。使用位域允许按名称使用这些单独的位,而不是对整个寄存器进行按位操作。

这主要是一种美学功能,但可以提高某些应用程序的代码可读性。

【讨论】:

除非它们不为此工作,除非您的编译器另有说明。 (当然,这会将您绑定到一个特定的编译器。但是大多数嵌入式系统无论如何都会或多或少地绑定到一个特定的编译器。)【参考方案2】:

位域有多种用例,即使在现代机器上也是如此。

第一个是当您处理寄存器级逻辑时。这在您设置模式以及某些硬件的工作方式时很常见。这在嵌入式设备上更为常见。例如,在 Arduino 设备上,“PinMode”逻辑基本上是将各个位设置为高或低,以指示数字 I/O 引脚是处于“输入”还是“输出”模式。

http://arduino.cc/en/Reference/pinMode

其次,在 C/C++ 程序中编写优化的内嵌汇编代码时。有时您希望利用硬件优化指令来尽可能加快程序的执行速度:

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

最后一个常见示例是编写数据包驱动程序或实现特定协议时。我最近刚刚发布了一个关于此的问题,结果发现我使用的是 32 位变量而不是由位域组成的 8 位变量,这导致我的代码中断:

Basic NTP Client in Windows in Visual C++

因此,简而言之:直接与硬件或网络代码对话时。

【讨论】:

【参考方案3】:

位域在现代、高 性能机器,但对于较小的机器,它们可以非常 对节省内存很有用,如果你有大的数组 结构。但是,除了节省内存之外,没有任何用处 给他们。

【讨论】:

这不仅仅是为了节省内存(事实上这可能是最不常见的用途之一)。 SoC 和微控制器的寄存器位域映射更有可能。例如,this PIC16 header 广泛使用位域,大多数微控制器和 SoC 的部分特定标头也是如此。 内联汇编在现代 CPU 上仍然很常见。例如,MATLAB 广泛使用特定于平台的优化。一些代码涉及显式设置特定寄存器。【参考方案4】:

除了其他答案之外,在某些场景下,使用位域可以同时提高内存使用率和性能。

通过将需要少量位来表示可能值范围的属性打包在一起来节省内存。为什么将 8 个布尔属性作为 8 个 bool 成员,当单个字节能够在每个位中存储 8 个布尔值时——而不是仅使用 1 个的 8 个字节,节省的 7 个字节非常重要。自然,您通常会使用 32、64 位或更宽的位域。 我有一个类似的场景,其中有很多具有很多属性的对象,这些属性可以用一位或几位来表示,对于具有高对象数(数百万)的情况,内存节省确实很重要。

提高性能 - 尽管位域会带来很小的性能损失(通过移位和屏蔽访问实际值),但这些操作非常快。打包更多数据并浪费更少位可以为您提供更好的缓存效率,这可以带来比位字段访问损失更大的性能增益。 不仅访问单个位可能比从缓存中获取另一行更快,而且如果打包后更有可能在缓存中找到数据,但这会减少对缓存的污染,为其他进程留出更多可用空间。

【讨论】:

以上是关于C 和 C++ 中的位域:它们在哪里使用?的主要内容,如果未能解决你的问题,请参考以下文章

澄清 C 中的位域排序语义

求大神指教C语言中的位域

C - 位矩阵的位域

C/C++ 位域知识小结

记录C中的位域

共享库中的位域可移植性