什么是零宽度位域

man*_*m-n 16 c signed struct bit-manipulation

可能重复:
实际使用零长度位域

为什么有些结构具有零宽度位域,为什么需要它?

struct foo {
  int    a:3;
  int    b:2;
  int     :0; // Force alignment to next boundary.
  int    c:4;
  int    d:3;
};

int main()
{
        int i = 0xFFFF;
        struct foo *f = (struct foo *)&i;
        printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述程序的输出是

manav@os-team:~/programs/test$ ./a.out
a=-1
b=-1
c=-8
d=0
Run Code Online (Sandbox Code Playgroud)

请解释为什么这些值是负数,以及结构内部这些变量的内存布局?

Pau*_*l R 9

谷歌搜索的第一次打击:

长度为0的位字段必须是未命名的.无法引用或初始化未命名的位字段.零宽度位字段可以使下一个字段在下一个容器边界上对齐,其中容器的大小与位字段的基础类型相同.

至于问题的第二部分,你将结构中的一些位域设置为全1,并且由于这些字段是有符号的,因此这会导致这些字段的负值.如果将整个结构设置为1并查看有符号和无符号表示中的值,则可以更有效地查看此内容,例如

int main()
{
    struct foo f;
    memset(&f, 0xff, sizeof(f));
    printf("a=%d\nb=%d\nc=%d\nd=%d\n", f.a, f.b, f.c, f.d); // print fields as signed
    printf("a=%u\nb=%u\nc=%u\nd=%u\n", f.a, f.b, f.c, f.d); // print fields as unsigned
    return 0;
}
Run Code Online (Sandbox Code Playgroud)