【问题标题】:why bit-fields for same data types have less in size compared to bit-fields for mix-data types为什么相同数据类型的位域与混合数据类型的位域相比具有较小的大小
【发布时间】:2009-03-10 06:44:08
【问题描述】:

我很想知道为什么具有相同数据类型的位字段比混合的位字段占用更少的大小 数据类型。

struct xyz 
{ 
  int x : 1; 
  int y : 1; 
  int z : 1; 
}; 


struct abc 
{ 
  char x : 1; 
  int y : 1; 
  bool z : 1; 
}; 

sizeof(xyz) = 4 sizeof(abc) = 12.

我正在使用 VS 2005,64 位 x86 机器。

有点机器/编译器级别的答案会很棒。

【问题讨论】:

    标签: c++ c bit-fields


    【解决方案1】:

    对齐。

    您的编译器将以对您的架构有意义的方式对齐变量。在您的情况下,charintbool 的大小不同,因此它将通过该信息而不是您的位字段提示。

    this question 有一些关于此事的讨论。

    解决方案是向编译器提供#pragma 指令或__attributes__ 以指示它忽略对齐优化。

    【讨论】:

    • 请注意,位域实际上并没有对齐要求。
    • 不,但编译器没有义务打包它们。
    • 参见 ISO14882:2003, §9.6, 第 1 段。
    • 学习机器架构和编译器构造对程序员仍然有用的另一个原因,尽管在 SO 上有些人否认这一点。
    【解决方案2】:

    C 标准(1999 年版本,§6.7.2.1,第 102 页,第 10 点)这样说:

    一个实现可以分配任何足够大的可寻址存储单元来容纳一个 位域。如果有足够的空间,一个位域紧跟在另一个位域之后 结构中的位域应打包到同一单元的相邻位中。

    似乎没有任何措辞允许包装受字段类型的影响。因此我会得出结论,这是一个编译器错误。

    gcc 在任何一种情况下都会在 Linux 下的 32 位和 64 位机器上创建一个 4 字节的结构。我没有VS,无法测试。

    【讨论】:

    • C++03, §9.6, 第 1 段说,“类对象中位域的分配是实现定义的。位域的对齐是实现定义的。位域被打包到一些可寻址的分配单元。”看来 mahesh 正在使用 C++ 编译器。
    • 另一方面,他也将此标记为 C 问题,而不仅仅是 C++。我猜 C 和 C++ 的答案是不同的。
    • 我会谨慎地声称这是一个“错误”,因为您引用了 ISO C99 标准。 MSVC++ 没有声称遵守 C99。它支持 ISO C90/ANSI C89。
    • PS:在位域中使用除 int 或 unsigned 以外的类型是对 C89/90 的扩展,因此所有关于行为的赌注都没有。
    • 如果 MSVC++ 不支持十年前的标准……听起来不是很令人印象深刻,是吗?
    【解决方案3】:

    这是编译器错误或一些代码错误。 结构中分配的所有位总是试图定义 sizeof 最高数据类型。 例如在 struct xyz sizeof 最高数据类型是 4 即 int。 以类似的方式,第二个结构 abc 的最高数据类型大小对于 int 是 4。

    好像我们改变结构的变量如下: 结构 abc { 字符:1; 字符 b:1; 布尔 c:1; };

    sizeof(abc) 将是 1 而不是 4。由于 size 最高数据类型为 1,并且所有位都适合 1 字节的 char。

    可以通过改变结构中的数据类型来执行各种测试。

    基于旧结构的输出链接: 访问http://codepad.org/6j5z2CEX

    基于我定义的上述结构的输出链接: 访问http://codepad.org/fqF9Ob8W

    为避免 sizeof 结构出现此类问题,我们将使用 #pragma pack 宏正确打包结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2013-07-18
      • 2012-10-17
      • 2021-10-09
      相关资源
      最近更新 更多