【问题标题】:What is the use of declaring different datatypes inside bitfields?在位域中声明不同的数据类型有什么用?
【发布时间】:2012-02-09 15:23:57
【问题描述】:

位域的典型用途是声明一个小于 8 位的空间有效变量。我不明白的是,将这些位声明为 short、int、long、bool 等的价值。例如

typedef struct{
    int first:3,
    short second:3,
    char third:3
    } somestruct;

在上述情况下,所有 3 个变量,即第一、第二和第三个都是 3 位长。将变量第一个声明为 int,第二个声明为 short,第三个声明为 char 的值是什么?

或者,为什么甚至需要数据类型?我应该能够将上述声明为

typedef struct{
    first:3,
    second:3,
    third:3
    } modifiedstruct;

modifiedstruct 假定变量 first、second 和 third 没有数据类型。将 3 位解释为字符、数字或浮点数的责任应该是 something else 的责任。

linux 上的 gcc 和 g++ 都允许上述行为。

【问题讨论】:

    标签: c bit-fields


    【解决方案1】:

    实际上,C 标准只允许位域的类型为有符号整数或无符号整数(以及 C99 中的 _Bool)。如果你可以在其中抛出一个 short、long 或 char,那就是编译器扩展。

    至于为什么,主要原因是签名。考虑:

    struct {
       int s: 3;
       unsigned u: 3;
    } bf;
    
    bf.s = 7;
    bf.u = 7;
    

    这两个位域都是 1。但是,C 保留符号,所以:

    (int)bf.s == -1    // Because signed conversions preserve the sign bit
    bf.s >> 1 == -1    // So do right shifts on signed values
    

    同时:

    (int)bf.u == 7     // Because the source is unsigned and so just a series of bits
    bf.u >> 1 == 3     // Unsigned right shifts are just moving bits around as well
    

    对于允许使用 char 的编译器,可能是同一种想法。 char 的默认符号是实现定义的,因此如果您希望位域的符号与编译器的 char 的符号相匹配,您可以将其定义为 char。

    【讨论】:

    • 我的整个问题是为什么要在 char(Bool) 和 int 等位域中引入不同的数据类型,其次,int x:2 和 char y:2 有什么区别?
    【解决方案2】:

    大小用于数据的存储(或传输)。数据类型是您打算如何使用和处理该信息。

    【讨论】:

      【解决方案3】:

      对位字段使用除int 之外的任何其他类型是实现定义的行为。因此,如果不知道您使用的是什么特定的编译器,就无法知道该代码的作用,或者它是否可以编译。

      通常,标准对位域的定义非常差,因此完全不可移植。由于位域也是 C 语言的一个多余特性,因此使用位运算符进行位操作很可能更明智。

      【讨论】:

        【解决方案4】:

        在位域中键入对我来说唯一重要的是有符号类型与无符号类型。对于大于 1 的字段,这可能会在分配期间对数据的解释方式产生影响。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-12
          • 1970-01-01
          • 1970-01-01
          • 2011-04-16
          • 2019-03-14
          • 2012-04-05
          相关资源
          最近更新 更多