在位域内声明不同数据类型有什么用?

时间:2012-02-09 15:23:57

标签: c bit-fields

位域的典型用法是声明小于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位解释为字符,数字或浮动的责任应由某事 else负责。

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

4 个答案:

答案 0 :(得分:5)

实际上,C标准只允许位域为signed int或unsigned int(以及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的默认签名是实现定义的,所以如果你想让bitfield的signedness匹配编译器的char的签名,你可以将它定义为char。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

对于位字段使用除int之外的任何其他类型是实现定义的行为。因此,在不知道您使用的是哪种特定编译器的情况下,无法确定该代码的作用,或者甚至是否编译。

一般来说,比特字段的标准定义很差,因此完全不可移植。由于位字段也是C语言的一个多余功能,因此使用逐位运算符进行位操作更为明智。

答案 3 :(得分:0)

bitfield中的类型对我来说唯一重要的时间是签名类型和无符号类型。对于大于1的字段,这可能会影响分配期间数据的解释方式。