I do have a structure having bit-fields in it.Its comes out to be 2 bytes according to me but its coming out to be 4 .I have read some question related to this here on stackoverflow but not able to relate to my problem.This is structure i do have
struct s{
char b;
int c:8;
};
int main()
{
printf("sizeof struct s = %d bytes \n",sizeof(struct s));
return 0;
}
if int type has to be on its memory boundary,then output should be 8 bytes but its showing 4 bytes??
Source: http://geeksforgeeks.org/?p=9705
In sum: it is optimizing the packing of bits (that’s what bit-fields are meant for) as maximum as possible without compromising on alignment.
A variable’s data alignment deals with the way the data stored in these banks. For example, the natural alignment of int on 32-bit machine is 4 bytes. When a data type is naturally aligned, the CPU fetches it in minimum read cycles.
Similarly, the natural alignment of
short intis 2 bytes. It means, a short int can be stored in bank 0 – bank 1 pair or bank 2 – bank 3 pair. Adoublerequires 8 bytes, and occupies two rows in the memory banks. Any misalignment of double will force more than two read cycles to fetch double data.Note that a double variable will be allocated on 8 byte boundary on 32 bit machine and requires two memory read cycles. On a 64 bit machine, based on number of banks, double variable will be allocated on 8 byte boundary and requires only one memory read cycle.
So the compiler will introduce alignment requirement to every structure. It will be as that of the largest member of the structure. If you remove
charfrom yourstruct, you will still get 4 bytes.In your
struct,charis 1 byte aligned. It is followed by anintbit-field, which is 4 byte aligned for integers, but you defined a bit-field.8 bits = 1 byte.
Charcan be any byte boundary. SoChar+Int:8= 2 bytes. Well, that’s an odd byte boundary so the compiler adds an additional 2 bytes to maintain the 4-byte boundary.For it to be 8 bytes, you would have to declare an actual
int(4 bytes) and achar(1 byte). That’s 5 bytes. Well that’s another odd byte boundary, so thestructis padded to 8 bytes.What I have commonly done in the past to control the padding is to place fillers in between my
structto always maintain the 4 byte boundary. So if I have astructlike this:I am going to insert allocation as follows:
That would give me a
structwith a size of 4 bytes + 1 byte + 3 bytes = 8 bytes! This way I can ensure that mystructis padded the way I want it, especially if I transmit it somewhere over the network. Also, if I ever change my implementation (such as if I were to maybe save thisstructinto a binary file, the fillers were there from the beginning and so as long as I maintain my initial structure, all is well!)Finally, you can read this post on C Structure size with bit-fields for more explanation.