【问题标题】:Why and how are C++ bitfields non-portable?为什么以及如何 C++ 位域不可移植?
【发布时间】:2016-07-05 07:19:40
【问题描述】:

我遇到了很多关于位域的各种问题的 cmet 断言位域是不可移植的,但我一直无法找到确切解释原因的来源。

从表面上看,我会假设所有位域都只是编译为相同位移代码的变体,但显然肯定还有更多,否则就不会对它们产生如此强烈的厌恶。

所以我的问题是是什么让位域不可移植?

【问题讨论】:

  • 在什么情况下他们被称为“不安全”?添加链接?
  • 我认为这主要是人们滥用位域来提取其他数据类型在子字节级别的表示,这是完全不可移植的。
  • 当然,如果您将位域用于安全用例,那么大/小位域布局与大/小整数布局无关。不过,人们似乎对不安全的用例更感兴趣。
  • 正确使用,位域是安全且可移植的。您可以滥用位字段并创建不可移植的代码,但这与滥用整数、指针等没有什么不同。

标签: c++ portability bit-fields


【解决方案1】:

位域是不可移植的,就像整数是不可移植的一样。您可以使用整数来编写可移植程序,但不能期望将int 的二进制表示原样发送到远程计算机并期望它正确解释数据。

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

这些问题很容易克服。原生字节序可以很容易地转换为约定的字节序(大字节序是网络通信的事实标准),并且可以在编译时检查大小,并且现在可以使用固定长度的整数类型。因此,只要注意这些细节,整数就可以用于跨网络通信。

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

  • 关于类对象中位域的实际分配细节的一切

    • 例如,在某些平台上,位字段不跨越字节,而在其他平台上却是
    • 此外,在某些平台上,位字段从左到右打包,在其他平台上从右到左打包
  • char、short、int、long 和 long long 位字段是有符号的还是无符号的(当未如此明确声明时)。

与字节序不同,将“关于实际分配细节的一切”转换为规范形式并非易事。

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


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

【讨论】:

    【解决方案2】:

    位字段是不可移植的,因为位的顺序是未指定的。因此,一个编译器的索引 0 位很可能是另一个编译器的最后一位。

    这可以防止在应用程序中使用位域,例如切换内存映射硬件寄存器中的位。

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

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

    【讨论】:

    • 位域布局是实现定义的,not 使位域不可移植。它是假定特定布局的代码,它是不可移植的。
    • @4386427:使用位域的一般原因是为了获得所需的布局,例如OS API 函数的参数中的选项位。问题是并非所有编译器都可能产生相同的结果(或者换句话说,标准没有为最常见的用例提供合理的保证)。最后,有人搞砸了,但不一定是原来的程序员。
    • @4386427 语言结构不可移植或不可移植。编译器是否支持它。在谈论可移植性时,我们总是谈论这些构造的使用。我认为没有必要精确说明这一点。
    • @fjardon - 同意 - 您评论的第一部分。这就是这个问题的全部问题。问题(以及您答案的第一部分)表明位字段不能以完全可移植的方式使用 - 这是导致错误的原因。经常使用位域在特定系统/编译器上获得特定布局的事实并不会使位域通常不可移植。位域的用例可以写成 100% 可移植。值得一提的是,IMO。
    猜你喜欢
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2019-02-17
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多