【问题标题】:struct bitfield max size (C99, C++)结构位域最大大小(C99,C++)
【发布时间】:2011-02-08 11:49:00
【问题描述】:

位结构字段的最大位宽是多少?

struct i { long long i:127;}

我可以在 struct 中定义一个位域,位域的大小最多为 128 位、256 位或更大吗?有一些超宽向量类型,如 sse2(128 位)、avx1/avx2(256 位)、avx-512(下一个 Xeon Phis 为 512 位)寄存器;还有像 gcc 中的 __int128 这样的扩展。

【问题讨论】:

  • 对于长位字段,您可能需要调查 中声明的 std::bitset。至于位限制,我建议首先阅读您的编译器文档以了解限制,因为这些限制通常比语言标准强加的更严格。
  • @Thomas Matthews,最大位字段大小的一般限制是什么?标准是否定义了一些上限?

标签: c++ c struct c99 bit-fields


【解决方案1】:

C99 §6.7.2.1,第 3 段:

指定的表达式 位域的宽度应为 整数常量表达式 不应为非负值 超过对象中的位数 指定的类型,如果 冒号和表达式被省略。如果 值为零,声明 应该没有声明符。

C++0xa §9.6,第 1 段:

... 常量表达式应为 带有 a 的整数常量表达式 值大于或等于零。 积分常数的值 表达式可能大于 对象中的位数 的表示(3.9) 位域的类型; 在这种情况下 额外位用作填充位 并且不参与价值 位域的表示(3.9)

所以在 C 中你根本不能这样做,而在 C++ 中它不会做你想做的事情。

【讨论】:

  • 您只是忘了提到在 C99 中唯一可以保证工作的类型是 _Boolsigned intunsigned int。特别是 OP 对 long long 的使用是特定于实现的。
  • @JensGustedt 也是标准限制吗?如果是这样,在 6.7.2.1 附近的某个地方?
  • @WhozCraig:该限制是 6.7.2.1 的第 4 段:“位域的类型应为 _Boolsigned intunsigned int 的合格或不合格版本,或其他一些实现定义的类型。”
  • @JensGustedt:如果实现支持列出的位字段类型以外的类型,则第 5 段中的限制仍然适用。如果实现不支持long long 位字段,long long i:127; 必须触发诊断。如果它确实支持它们,那么它必须被诊断为CHAR_BIT * sizeof (long long) < 127(对于我见过的每个实现都是如此,但不是强制性的)。此注释仅适用于 C,不适用于 C++。
【解决方案2】:

C++ 标准对位域的大小没有任何限制,除了它必须大于或等于零 - 第 9.6/1 节。它还说:

位域被打包成一些 可寻址分配单元。 [笔记: 位域跨越分配单元 在某些机器上而不是在其他机器上。 位域从右到左分配 在某些机器上,从左到右 其他。 ]

我想这可以用来表示某种最大尺寸。

当然,这并不意味着您的特定编译器实现支持任意大小的位域。

【讨论】:

  • @osgx 我不知道 - 我从来没有在自己的代码中使用过位域,所以这对我来说不是问题。
  • @osgx:GCC 支持古怪的位域大小。过大的位域(即使 char a : 10; 也只是浪费了额外的位。
【解决方案3】:

通常,您不能分配比基础类型更多的位。如果long long 是 64 位,那么您的位域可能仅限于 :64。

【讨论】:

  • 如果我将使用 mmx/sse2 类型(128 或 256 位),我可以将其中的 3/4 分配为位域吗?
  • 就编译器而言,这些不是整数类型,因此它们对您可以声明的位域的最大宽度没有影响。
【解决方案4】:

由于位域的值被分配给整数,我假设您可以使用的最大位域值是 intmax_t 的大小。

编辑:

来自 C99 规范:

6.7.2.1 项目符号 9:

位域被解释为有符号的 或无符号整数类型,包括 指定的位数。如果 值 0 或 1 存储到 类型的非零宽度位域 _Bool,位域的值应与该值比较 存储。

6.7.2.1 项目符号 10:

一个实现可以分配任何 足够大的可寻址存储单元 保存一个位域。如果空间足够 仍然是一个位域,立即 在 a 中跟随另一个位域 结构应装入 同一单元的相邻位。如果 剩余空间不足,无论是 不适合的位域被放入 下一个单元或重叠相邻 单位是实现定义的。这 位域的分配顺序 在一个单元内(从高阶到低阶 或低阶到高阶)是 实现定义。对齐方式 可寻址存储单元的 未指定。

【讨论】:

  • 我的问题示例:long long i。我最多可以使用这个 longlong 的 64 位作为 bitfiled,它大于 int
  • 这些引用不支持你的假设……
  • 规范的哪一部分不支持我的假设? “位域被解释为有符号或无符号整数类型。”这意味着最大的位域大小是最大整数类型的大小。我包括了第 10 个项目符号,因为我对该项目符号的解释是任何大小的存储单元(大于零位)都可以有一个位字段。只要位域大小小于 intmax_t,这似乎支持 OP 将位域添加到“超宽向量类型”的愿望。如果我解释错了,请纠正我。
猜你喜欢
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
相关资源
最近更新 更多