Reputation: 95
This is my program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
struct bitfield {
unsigned a:3;
char b;
unsigned c:5;
int d;
}bit;
printf("%lu \n",sizeof(bit));
return 0;
}
I was expecting size of this structure to be, well quite a lot, but it comes out to be 8 on my machine, because unsigned is 4 bytes. Now reason I was expecting to be more than that was because I would expect char b
to be on a byte boundary, so that it is aligned in the memory correctly. Now my guess is that compiler is putting a, b, c, all in those 4 bytes. I am new to C, so please bear with me. Is my assumption that all the other data types besides bit fields have to be necessarily on byte incorrect? If it is correct, I would expect, a
to take the whole unsigned int, and b
to take a byte and then padding of 3 bytes, and then so on. What am I missing here?
Upvotes: 0
Views: 1397
Reputation: 19221
I don't seem to understand the conflict.
you basically have:
struct bitfield {
unsigned a:3;
unsigned padding1:5;
char b;
unsigned c:5;
unsigned padding2:3;
unsigned padding3:8;
int d;
}bit;
a
is on byte 1 boundary, it uses three bits + 5 bit padding (because there aren't any more bit fields to use up the leftover bits).
b
is on byte 2 boundary, it uses a whole byte.
c
is on byte 3 boundary, it uses five bits + 3 bit padding (because there aren't any more bit fields to use up the leftover bits).
- int padding comes here -
d
is on an int
boundary (4 bytes on your machine). It uses 1 byte for padding + 4 bytes for data.
All together, 8 bytes...
... although, as pointed out by @ JonathanLeffler in the comments, this is implementation specific and doesn't mean every compiler will behave the same.
Upvotes: 3
Reputation: 949
You usually align the bitfields in that way they share a single byte together. When you place another variable in between bitfields, the unused bits end up using space in memory you don't need but still use space.
I tested your code with some values and ran the program in gdb.
bit.a = 1;
bit.b = 'a';
bit.c = 4;
bit.d = 1337;
When printing the memory in gdb, the output looks like this
(gdb) x/8b &bit
0x7fffffffe118: 00000001 01100001 00000100 00000000
00111001 00000101 00000000 00000000
So we see that the first byte is completely used from field a, although it only uses 3 bits. The character a in field b also takes up a byte. The third byte (00000100
) matches value 4 of field c and here's whats interesting:
You then have an integer which uses 4 bytes (in the gdb output above the last 4 bytes, bottom line), but there's an extra zero byte in there. This is a common pratice for compilers as they try to align the memory in an optimized way.
Upvotes: 2