【问题标题】:Bit-Fields in C/C++: what is guaranteed, what is implementation-defined?C/C++ 中的位域:什么是保证的,什么是实现定义的?
【发布时间】:2023-01-31 00:10:34
【问题描述】:

阅读https://en.cppreference.com/w/c/language/bit_field,以下结论是否正确?

  • 相邻的位字段之间没有填充(这似乎与 C 标准的 6.7.2.1 不同)。
  • 位字段在存储单元中的放置是实现定义的。
  • 位域中位的位置是实现定义的。

(对于 C++,另请参阅:Characteristics of bit-Fields in C++。)

【问题讨论】:

  • 请选择一种语言。
  • 除了列出的 3 个,还有其他实现定义的特性。建议参考语言规范并检查其指数为了位域.
  • 特别是我的第一点和第三点在引用的文档中没有回答我。
  • 是的,链接文档适用于 C++。关于我的上述观点,我对 C 文档也不清楚。
  • wimalopaan,这个问题很广泛。几乎是对每一个方面的要求位域.也许更窄一些?

标签: c bit-fields implementation-defined-behavior


【解决方案1】:

作为初步,没有问题标题引用的语言“C/C++”。 C 和 C++ 是截然不同的语言,它们共享一个公共子集。特别是,C 不是 C++ 的子集。

关于 C,当前语言规范(目前为 C17)提供的有关位域布局的所有细节都在第 6.7.2.1/11-12 段中。

以下结论是否正确?

  • 相邻的位字段之间没有填充(这似乎与 C 标准的 6.7.2.1 不同)。

位字段不直接布置在结构中。 C 实现在结构中为它们布置“可寻址存储单元”,并在其中布置位域。 ASU 的大小和对齐要求未指定。

规范也就是说,如果分配了一个位域的 ASU 中有足够的空间,那么紧随其后的位域将被打包到同一 ASU 的相邻位中。这意味着这些位域之间没有填充位。但是,如果没有足够的空间,则由实现定义紧随其后的位域是否跨越两个 ASU,或者是否将其所有位分配给一个单独的位,将未使用(填充)位留在第一个。此外,零宽度位域可用于力量它后面的位域被分配给一个新的 ASU,可能需要在前一个 ASU 中填充位。

此外,该规范没有说明 ASU 之间是否有填充字节。 ASU 不需要大小统一或彼此具有相同的对齐要求,因此有时在它们之间需要填充字节是合理的,即使在这方面并非故意违反常理的实现中也是如此。

  • 位字段在存储单元中的放置是实现定义的。

该规范明确指出命令ASU 中的位域数量是实现定义的。这是从右到左对比从左到右的感觉。 “订单”与“放置”并不完全相同,但我想这就是您的意思。

  • 位域中位的位置是实现定义的。

并不真地。这是representation的问题,不是layout的问题,C17的相关段落是6.2.6.1/3-4:

存储在无符号位字段和unsigned char 类型对象中的值应使用纯二进制表示法表示。

[...] 存储在位字段中的值由 m 位组成,其中 m 是 为位域指定的大小。对象表示是集合 m位的位字段包含在可寻址存储单元中 拿着它。

如果需要,脚注 49 阐明了“纯二进制表示法”的含义。位域表示的所有其他细节是未指定,不是实现定义的,这意味着你不能依赖它们被记录下来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2010-11-16
    • 2015-08-13
    • 2010-10-12
    相关资源
    最近更新 更多