How does gcc calculate the required space for a structure?
struct {
integer a;
struct c b;
...
}
开发者_运维问答
In general how does gcc calculate the required space? Is there anyone here who has ever peeked into the internals?
I have not "peeked at the internals", but it's pretty clear, and any sane compiler will do it exactly the same way. The process goes like:
- Begin with size 0.
- For each element, round size up to the next multiple of the alignment for that element, then add the size of that element.
- Finally, round size up to the least common multiple of the alignments of all members.
Here's an example (assume int
is 4 bytes and has 4 byte alignment):
struct foo {
char a;
int b;
char c;
};
- Size is initially 0.
- Round to alignment of
char
(1); size is still 0. - Add size of
char
(1); size is now 1. - Round to alignment of
int
(4); size is now 4. - Add size of
int
(4); size is now 8. - Round to alignment of
char
(1); size is still 8. - Add size of
char
(1); size is now 9. - Round to lcm(1,4) (4); size is now 12.
Edit: To address why the last step is necessary, suppose instead the size were just 9, not 12. Now declare struct foo myfoo[2];
and consider &myfoo[1].b
, which is 13 bytes past the beginning of myfoo
and 9 bytes past &myfoo[0].b
. This means it's impossible for both myfoo[0].b
and myfoo[1].b
to be aligned to their required alignment (4).
There's not truely standardized way of aligning a struct, but the rule of thumb goes like this: The entire struct is aligned at a 4 or 8 byte boundary (depending on the platform). Within the struct, each member is aligned by its size. So the following packs with no padding:
char // 1
char
char
char
short int // 2
short int
int // 4
This will have a total size of 12. However, this next one will cause padding:
char // 1, + 1 bytes padding
short // 2
int // 4
char // 1, + 1 byte padding
short // 2
char // 1
char // 1, + 2 bytes padding
Now the structure takes up 16 bytes.
This is just a typical example, the details will depend on your platform. Sometimes you can tell a compiler to never add any padding -- this cause more expensive memory access (possibly introducing concurrency problems) but will save space.
To lay out aggregates as efficiently as possible, order the members by size, starting with the biggest.
The size of a structure is implementation defined, but it is hard to say what the size of your structure will be without more information (it is incomplete). For instance, given this struct
:
struct MyStruct {
int abc;
int def;
char temp;
};
Yields a size of 9 on my compiler. 4 bytes for int
and 1 byte for a char
.
Have modified your code so that it compiles and ran it on Eclipse/Microsoft C compiler platform:
struct c {
int a;
struct c *b;
};
struct c d;
printf("\nsizeof c=%d, sizeof a=%d, sizeof b=%d",
sizeof(d), sizeof(d.a), sizeof(d.b));
printf("\naddrof c =%08x", &c);
printf("\naddrof c.a=%08x", &c.a);
printf("\naddrof c.b=%08x", &c.b);
The above code fragment produced the following output:
sizeof c=8, sizeof a=4, sizeof b=4
addrof c =0012ff38
addrof c.a=0012ff38
addrof c.b=0012ff3c
Do something like this so you can see (WITHOUT GUESSING) exactly how your compiler formats a structure.
精彩评论