位域,为什么要实现特定?

11

C/C++ 位域在硬件驱动程序和二进制网络传输中似乎有很多应用,但它们并不常用并且通常受到约束,因为实际的二进制布局是特定于实现的,正如C99标准6.7.2.1/10-"结构和联合说明符"中所示:

一个实现可以分配任何足够大以容纳位域的寻址存储单元。如果剩余空间足够,紧随结构中另一个位域后面的位域将被打包到同一单元的相邻位中。如果剩余空间不足,没有适合的位域则根据实现定义放入下一个单元或重叠相邻单元,位域在单元内的分配顺序(高到低或低到高)由实现定义。可寻址存储单元的对齐方式未指定。

我的问题很简单:为什么委员会决定让位域成为实现特定的东西,从而使其成为编译器构造,主要用于减少内存使用,而在许多情况下,它本可以用于提供良好的二进制布局,并使开发人员免于位操作代码?


2
我相信每个字节的位数不一定是8这个事实也与此有关。 - Drew McGowen
@Mr Lister:关于确保字段在下一个字节中对齐,因此不会从字节中间开始,我们已经有了零大小的位域,对吧?- 所以这已经是标准规定了。 - Skeen
@Mr Lister:关于字节序,这是有道理的,但他们本应该添加一个特定的说明符来强制特定的字节序,并且如果没有包含这个参数,则默认使用机器的字节序,这不仅可以解决位域的问题,也可以用于传输任何多字节数据结构。 - Skeen
@John Dibling:我理解这一点,但为什么不像FORTRAN中的CONVERT那样,可以要求处理特定结构时使用特定字节顺序呢?默认情况下它使用标准字节顺序,但可以要求使用特定的字节顺序。 - Skeen
1
@Skeen:是的,在这种情况下,标准委员会的默认行为是将其留给编译器(实际上是硬件)。你可以揪着手争论“为什么”,但这只是在对着雨喊叫。C++语言的一个基本特征是许多这种决策都留给了具体实现。 - John Dibling
显示剩余4条评论
1个回答

8
出于同样的原因,许多其他事情也没有被标准严格规定:为了在大量平台和系统上生产合规的编译器并仍然拥有高效的编译器,需要灵活性。特别是,要求按特定位/字节顺序存储位域将使其在自然字节顺序相反的机器上变得非常慢。是的,这意味着在多个架构和平台之间使位域可移植是一件非常麻烦的事情。如果您真的需要这样做,那么或许应该考虑其他解决方案...

1
所以,至少在我的世界里,这意味着为了避免可能的缓慢功能,他们最终得到了一个大部分无法使用的功能? - Skeen
2
不,只要你不需要它非常易于移植,它就可以完全可用。请注意,在许多体系结构中,主要的区别将是字节顺序,而不是位顺序,因此只要处理器相同,您就可以使用。我相信如果它不高效(但是完全可移植且定义良好),大多数人也会抱怨得非常厉害。 - Mats Petersson
1
你可能是对的,但我宁愿拥有一个可移植的、定义良好的位域,然后在需要性能时自己进行位操作,而不是相反。 - Skeen
但是你也可以从另一个角度看待它——如果你想要严格的字节顺序和位顺序,你需要自己进行位操作。如果你想要一些相对快速和相对可移植的东西(记住,只有当你在一台机器上存储二进制值并在另一台机器上恢复二进制值或类似的情况下才会出现问题——当你不这样做时,它将正常工作)。 - Mats Petersson
+1 - 一切都好。另一个说明性的复杂性是,跨越两个字的位域可能需要比另一个CPU更多的指令或惩罚时钟周期,从而导致对紧密打包的不同态度。 - Tony Delroy
请注意,这已经是针对特定实现的30多年了,并且破坏约1000亿行现有的C代码(保守估计)并不是一个好主意。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接