Reputation: 165
I have read articles and SO answers about how we can cutoff compiler added padding if we layout the structs in the decreasing order of size of independent fields.
eg: Instead of laying out (L1) the struct like this
typedef struct dummy {
char c1;
short s1;
int i1;
unsigned int ui1;
double d1;
} dummy_t;
create the layout (L2) like this
typedef struct dummy {
double d1;
unsigned int ui1;
int i1;
short s1;
char c1;
} dummy_t;
My question here is, are there scenarios where layout L2 has downsides when compared to L1 or any other layout ? Or can I take it into my design rules to always use L2 ? Also is the natural alignment rule
natural alignment = sizeof(T)
always true for primitive types ?
Upvotes: 0
Views: 2456
Reputation: 67476
IMO abstracting from the implementation details like caching (which is too broad to be discussed in the post answer) there is no difference.
The difference is if you place the variable sized (or zero sized) object at the end of the struct (example):
typedef struct
{
size_t size;
char data[];
}string;
string *create(size_t size)
{
string *ptr = malloc(sizeof(*ptr) + size);
if(ptr)
{
ptr -> size = size;
}
return ptr;
}
If course the logical member order (and potential packing) is required if struct will store some received binary data (for example communication packet header)
Upvotes: 1
Reputation: 222272
My question here is, are there scenarios where layout L2 has downsides when compared to L1 or any other layout ?
Sometimes you need to have members in a different order. Reasons for this may include:
Also, there may be incidental effects of how members are ordered. For example, if member x
happens to be used much more frequently than other members of the structure, putting it at the front might allow the compiler to access it with simpler address arithmetic, since its offset from the beginning of the structure will be zero. This is rarely a consideration in programming, but I mention it for completeness.
Aside such considerations, you are generally free to order members as you desire.
Also is the natural alignment rule
natural alignment = sizeof(T)
always true for primitive types ?
No. As an example, an eight-byte long
might have an alignment require of one, two, four, or eight bytes.
… we can cutoff compiler added padding if we layout the structs in the decreasing order of size of independent fields.
This is not true for members that are aggregates (arrays, structures, and unions). Consider that a member char x[13];
is 13 bytes in size but only requires alignment of one byte. To minimize padding, order members in order of decreasing alignment requirement, not decreasing size.
Upvotes: 1
Reputation: 3323
You should wonder about alignement/structure size only if you are running on a memory constrained system (you want to limit the size of each element). This makes sense only for systems/designs where you know you will store a lot of such structure and used storage space is an issue. On the other hand grouping the content of a structure logically can bring clarity to your code. I would always favor clarity against performance, especially at early design phases. Even more if you do not have performance related constraints.
About performance it might happen that accessing "random" content from L2 is worse than from L1 because memory cache alignement constraints can also come into play. (eg accessing in a row 2 elements of struct L1 can be slower or quicker than 2 elements of L2). For such optimization, profiling is the only way to know which layout is the best.
Upvotes: 4