문제

Possible Duplicate:
Practical Use of Zero-Length Bitfields

Why some structures have zero-width bit fields, and why is it required?

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;
}

The output of above program is

manav@os-team:~/programs/test$ ./a.out
a=-1
b=-1
c=-8
d=0

Please explain why these values are negative, and the memory layout of these variables inside the structure?

도움이 되었습니까?

해결책

From this first hit on a Google search:

Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next container boundary where the container is the same size as the underlying type of the bit field.

As for the second part of your question, you set some of the bitfields in your struct to all 1s, and since these fields are signed then this results in a negative value for these fields. You can see this more effectively if you set the entire struct to 1s and look at the values in both signed and unsigned representations, e.g.

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;
}

다른 팁

The memory layout is "it depends" and you can't count on any particular layout from any particular compiler. In fact, you may see different layout from any given compiler by changing its settings. Don't try to guess, intuit, or depend on the layout.

Negatives - all your elements are ints which are signed, so they are negative since you've initialized every bit to 1, so you've got sign bits set. As for d - beats me. Typo?

As stated here, zero-length bitfields add alignment between bitfields. If we have several bitfields in a row, their layout is compact, but if we want to align one of them to byte/word/dword boundary, we need to put a zero-length bitfield between this and the previous one.

Example from the link above:

struct on_off {
                  unsigned light : 1;
                  unsigned toaster : 1;
                  int count;            /* 4 bytes */
                  unsigned ac : 4;     // this and
                  unsigned : 4;        // this and
                  unsigned clock : 1;  // this bitfields are next to each other
                  unsigned : 0;
                  unsigned flag : 1;   // this bitfield is at a 4 bytes boundary.
                 } kitchen ;

Numbers are negative because the bitfields are signed, i.e. if you have a signed char variable, its size is 8 bits which can hold 256 different values. Half of the values are positive, the rest are negative and 0. The most significant bit indicates sign (1 for negative, 0 for positive). Regarding zero-length bitfields see here: Practical Use of Zero-Length Bitfields

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top