Search code examples
c++cmemoryoutputbit-fields

memory layout of bitfield in C - can't understand the output


I have this code - http://ideone.com/sXhWxf

#include <stdio.h>

int main(void) {

struct bitfield{
    unsigned a:5;
    unsigned c:5;
    unsigned b:6;
} bit = {1,3,3};

char *p = (char*)&bit;
printf("%d\n",*p);
p++;
printf("%d\n",*p);
// I assumed that the bits are laid out in the below order in the memory.
// Spaces are just for clarity
// 00001 00011 000011
// Also, I asumed that the 'char' will take 8 bits. But I can't understand output.
// According to me the output should be - 8 195 (considering the 1st 8 bits & 
// last eight bits for the printf statements)
return 0;

}

The output is -

97
12

Can someone help me understand this output in detail? (Please read comments in the code)

Also, I came across this statement on Wikipedia which says "The members of bit fields do not have addresses, and as such cannot be used with the address-of (&) unary operator. The sizeof operator may not be applied to bit fields." But I am able to access the address of 'bit' variable. How is that? Am I not interpreting the statement correctly? Please guide me.


Solution

  • Assuming that integers are 32 bits on your target machine, the compiler has laid out the bit structure like this:

    bit 31                            bit 0
    |                                 |
    xxxxxxxxxxxxxxxx bbbbbb ccccc aaaaa
    

    where the x bits are unused.

    With a=1, c=3, b=3, this becomes

    0000000000000000 000011 00011 00001
    

    Split into bytes:

    00000000 00000000 00001100 01100001
    

    In decimal:

    0 0 12 97
    

    When stored as a little-endian integer, the byte order is 97 12 0 0, which explains your output.

    As for your second question: you are taking the address of the bit structure, not of any of its bitfields. char *p = (char*)&bit.a; would not work.