2

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.

halkujabra
  • 2,844
  • 3
  • 25
  • 35

3 Answers3

6

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.

TonyK
  • 16,761
  • 4
  • 37
  • 72
0

you are trying to access the adress of the sturcture not the bitfields, That's why you are able to acess the char p = (char)&bit;

you cannot do something like this char p = (char)&(bit.a);

Now comming to the actual point:

Accesing the bit fields using the address is not recommended as the packing of the bit fields in memory depends on lots of parameters.

0

Borrowing from another answer over here (Memory layout of struct having bitfields), the C specification does not make any guarantees as to the ordering of bitfields:

An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.

In which case, let's take a look at the output from your example.

97 translates to 01100001. If we separate, we can see our members as ...011 00001. 12 translates to 000011 00, which makes up the rest of our data structure. The compiler has packed each variable into memory lowest-bit first rather than highest-bit first, as you assumed.

As this is implementation-defined, it's unrecommended to use this unless you know exactly what your compiler will do with the code.

See here for more information and examples: C/C++: Force Bit Field Order and Alignment

Community
  • 1
  • 1
slugonamission
  • 9,562
  • 1
  • 34
  • 41