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

Jim*_*imm 3 c bit-fields

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

typedef struct{
    int first:3,
    short second:3,
    char third:3
    } somestruct;
Run Code Online (Sandbox Code Playgroud)

在上述情况下,所有3个变量,即第一,第二和第三变量都是3位长.将变量首先声明为int,将第二个声明为short,将第三个声明为char的值是多少?

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

typedef struct{
    first:3,
    second:3,
    third:3
    } modifiedstruct;
Run Code Online (Sandbox Code Playgroud)

modifiedstruct假定变量first,second和third没有数据类型.解释3位的字符,数字或浮动应该是责任的责任的东西别人.

Linux上的gcc和g ++都允许上述行为.

小智 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;
Run Code Online (Sandbox Code Playgroud)

这两个位域都是1.但是,C保留了符号,因此:

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

而:

(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
Run Code Online (Sandbox Code Playgroud)

对于允许char的编译器,它可能是同样的想法.char的默认签名是实现定义的,因此如果您希望bitfield的签名与编译器的char的签名匹配,则可以将其定义为char.