Possible Duplicate:
Why doesn't GCC optimize structs?
Why doesn't C++ make the structure tighter?
Consider the following example on a 32 bit x86 machine:
Due to alignment constraints, the following struct
struct s1 {
char a;
int b;
char c;
char d;
char e;
}
could be represented more memory-efficiently (12 vs. 8 bytes) if the members were reordered as in
struct s2 {
int b;
char a;
char c;
char d;
char e;
}
I know that C/C++ compilers are not allowed to do this. My question is why the language was designed this way. After all, we may end up wasting vast amounts of memory, and references such as struct_ref->b
would not care about the difference.
EDIT: Thank you all for your extremely useful answers. You explain very well why rearranging doesn't work because of the way the language was designed. However, it makes me think: Would these arguments would still hold if rearrangement was part of the language? Let's say that there was some specified rearrangement rule, from which we required at least that
- we should only reorganize the struct if actually necessary (don't do anything if the struct is already "tight")
- the rule only looks at the definition of the struct, not inside inner structs. This ensures that a struct type has the same layout whether or not it is internal in another structure
- the compiled memory layout of a given struct is predictable given its definition (that is, the rule is fixed)
Adressing your arguments one by one I reason:
Low-level data mapping, "element of least surprise": Just write your structs in a tight style yourself (like in @Perry's answer) and nothing has changed (requirement 1). If, for some weird reason, you want internal padding to be there, you could insert it manually using dummy variables, and/or there could be keywords/directives.
Compiler differences: Requirement 3 eliminates this concern. Actually, from @David Heffernan's comments, it seems that we have this problem today because different compilers pad differently?
Optimization: The whole point of reordering is (memory) optimization. I see lots of potential here. We may not be able to remove padding all together, but I don't see how reordering could limit optimization in any way.
Type casting: It seems to me that this is the biggest problem. Still, there should be ways around this. Since the rules are fixed in the language, the compiler is able to figure out how the members were reordered, and react accordingly. As mentioned above, it will always be possible to prevent reordering in the cases where you want complete control. Also, requirement 2 ensures that type-safe code will never break.
The reason I think such a rule could make sense is because I find it more natural to group struct members by their contents than by their types. Also it is easier for the compiler to choose the best ordering than it is for me when I have a lot of inner structs. The optimal layout may even be one that I cannot express in a type-safe way. On the other hand, it would appear to make the language more complicated, which is of course a drawback.
Note that I am not talking about changing the language - only if it could(/should) have been designed differently.
I know my question is hypothetical, but I think the discussion provides deeper insight in the lower levels of the machine and language design.
I'm quite new here, so I don't know if I should spawn a new question for this. Please tell me if this is the case.
struct
s out in both efficient and inefficient manners, depending on which is better for the task at hand, without having to mess around with compiler settings or directives to do so. If automatic reordering was ever added to the standard, it would have to be opt-in instead of opt-out, likely with a standardised preprocessor directive (perhaps#realign x
or#realign(x)
, wherex
is an integer value indicating the desired bit alignment). – Catapultstruct
basis, with the directive specified for eachstruct
that needs automatic realignment. [Additionally, either the compiler would be explicitly required to parse the entire struct before it begins working on it, or the preprocessor directive would have to be placed at the start of thestruct
definition, before any members are listed.] – Catapult