为什么以及如何使C ++位域不可移植?

问题描述 投票:7回答:2

关于位域声称位域是不可移植的各种问题我都遇到过很多评论,但是我从来没有能够找到解释原因的来源。

从表面上看,我会假设所有的位域只是编译成相同的位移代码的变化,但显然必须有更多的,或者不会有这样的激烈不喜欢它们。

所以我的问题是什么使bitfields不可移植?

c++ portability bit-fields
2个回答
13
投票

比特字段是非便携式的,因为整数是不可移植的。您可以使用整数来编写可移植程序,但是您不能期望将int的二进制表示形式发送到远程计算机并期望它正确地解释数据。

这是因为1.处理器的字长不同,因此,整数类型的大小不同(1.1字节长度也可能不同,但现在这种情况在嵌入式系统之外很少见)。并且因为2.字节字节序在处理器之间不同。

这些问题很容易克服。原生字节顺序可以很容易地转换为商定的字节顺序(big endian是网络通信的事实标准),并且可以在编译时检查大小,并且这些天可以获得固定长度的整数类型。因此,只要这些细节得到处理,整数就可以用于通过网络进行通信。

位字段构建在常规整数类型上,因此它们具有相同的字节顺序和整数大小的问题。但是他们有even more实现指定的行为。

  • 关于类对象中位字段的实际分配细节的一切 例如,在某些平台上,位字段不会跨越字节,而在其他平台上则不会 此外,在某些平台上,位字段从左到右打包,而在其他平台从右到左打包
  • 无显式签名或无符号的char,short,int,long和long长位字段是有符号还是无符号。

与endianness不同,将“关于实际分配细节的所有内容”转换为规范形式并非易事。

此外,虽然字节顺序是特定于cpu体系结构的,但位字段详细信息特定于编译器实现者。因此,即使在同一台计算机内的不同进程之间,位字段也不可移植,除非我们可以保证它们是使用相同(或二进制兼容)编译器编译的。


TL; DR位字段不是计算机之间通信的可移植方式。整数也不是,但它们的不可移植性很容易解决。


4
投票

在未指定位的排序的意义上,位字段是不可移植的。所以索引0的位与一个编译器很可能是另一个编译器的最后一位。

这可以防止在诸如在存储器映射的硬件寄存器中切换位的应用中使用位字段。

但是,您会看到硬件供应商在他们发布的代码中使用位域(例如微芯片)。通常,这是因为它们还使用它释放编译器或以单个编译器为目标。例如,在微芯片的情况下,源代码的许可证要求您使用自己的编译器(对于8位低端设备)

@Pharap指向的链接包含与此未指定顺序相关的(c ++ 14)规范的摘录:is-there-a-portable-alternative-to-c-bitfields

© www.soinside.com 2019 - 2024. All rights reserved.