【问题标题】:Is the integer width relevant in bitfield declaration?位域声明中的整数宽度是否相关?
【发布时间】:2012-04-22 19:22:01
【问题描述】:

我想找一个不应该写的理由

struct bitfield {
  signed foo:4;
  unsigned bar:2;
};

而不是详细地指定

struct bitfield {
  signed int foo:4;   
  unsigned int bar:2; 
};

由于位域的每个成员的大小都在冒号后明确指定,是否有任何缺点?

如果我使用charshortlonglong long,这有关系吗?指定的位域位数必须可能总是小于声明类型的宽度吗?


找到一些相关问题:

答案范围从

  • 不要使用除(有符号/无符号)int_Bool 之外的任何其他类型和
  • _Boolsigned intunsigned int 或其他一些实现定义的类型。 (C99 6.2.7.1 (4) )

在这种情况下:这种非特定的其他一些实现定义的类型可能是什么样的,我在这个地方的选择可能会产生什么其他缺点?

【问题讨论】:

  • 很遗憾,我不是回答这个问题的合适人选,但这个问题让我很好奇,我浏览了一下网页。 C90、C99 和 C++ 对允许的类型都有不同的定义,更糟糕的是,似乎有些编译器使用类型来确定结构的最小大小(即 long long foo:1 可能导致更大的结构然后是 int foo:1) bytes.com/topic/c/answers/… 有关于该主题的有趣信息

标签: c integer bit-fields


【解决方案1】:

“有时”和“是”

C99 要求宽度表达式“不超过指定类型的对象中的位数”,因此如果使用的类型太小,代码要么无法编译,要么无法编译。至少不便携。见 §6.7.2.1 (3)。

关于更新后的第三个问题和一般问题,“究竟是什么后果?” 问题,可能受到影响的事情是:可移植性、对齐和填充。该标准仅对第一个给出了明确的规范。如果没有位域,通常可能会根据预测编译器会做什么来生成最佳对齐值来安排对齐和填充。虽然不能保证,但在某些环境中使用 short 之类的东西似乎会因为减少对齐和填充而节省内存。

实现精确布局和可移植性偶尔冲突目标的一种可能方法是声明不带位字段的内存数据结构,可能使用<stdint.h> 类型。然后,如果您想使用位字段来解码某些内容,请将内存中的源对象分配给一个临时变量,该变量是位字段和位特定类型的联合,或者通过强制转换来故意违反类型双关规则指针。 (Linux 无处不在。)

更好的方法可能是避免位域。

【讨论】:

    【解决方案2】:

    在您的代码的两个版本中,宽度都是明确的;它是有符号和无符号int 的宽度。 signed 只是 int 的别名,signed int 也是如此。同样,unsignedunsigned int 的别名。 Lone signedunsigned 不是修饰符,而是类型名称本身。

    【讨论】:

    • 确实,但我问的是为什么我要选择short 而不是int 或类似的。
    • 不,我认为这里的signed 不是多余的。 int 位域可以具有无符号类型的语义。 J.3.9 将此标记为实现定义的行为。
    • 确实,我忘记了那个丑陋的特例。
    猜你喜欢
    • 1970-01-01
    • 2013-02-26
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多