Visual C++ offers both a compiler switch (/Zp
) and the pack
pragma to affect the aligment of struct members. However, I seem to have some misconception as to how they work.
According to MSDN, for a given alignment value n,
The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.
Let's assume a pack value of 8 bytes (which is the default). Within a struct, I'd think that any member whose size is less than 8 bytes will be at an offset that is a multiple of its own size. Any member whose size is 8 bytes or more will be at an offset that is a multiple of 8 bytes.
Now take the following program:
#include <tchar.h>
#pragma pack(8)
struct Foo {
int i1;
int i2;
char c;
};
struct Bar {
char c;
Foo foo;
};
int _tmain(int argc, _TCHAR* argv[]) {
int fooSize = sizeof(Foo); // yields 12
Bar bar;
int fooOffset = ((int) &bar.foo) - ((int) &bar); // yields 4
return 0;
}
The Foo
structure is 12 bytes in size. So within Bar
, I'd expect the Foo
member to be at offset 8 (a multiple of 8) while actually it's at offset 4. Why is that?
Also, Foo
really only has 4+4+1 = 9 bytes of data. The compiler automatically adds padding bytes at the end. But again, given an alignment value of 8 bytes, shouldn't it pad to a multiple of 8 rather than 4?
Any clarification appreciated!
Data structure alignment is the way data is arranged and accessed in computer memory. Data alignment and Data structure padding are two different issues but are related to each other and together known as Data Structure alignment.
Alignment helps the CPU fetch data from memory in an efficient manner: less cache miss/flush, less bus transactions etc. Some memory types (e.g. RDRAM, DRAM etc.) need to be accessed in a structured manner (aligned "words" and in "burst transactions" i.e. many words at one time) in order to yield efficient results.
Pointer alignment refers to the ILE COBOL compiler's process of positioning pointer items within a group item to offsets that are multiples of 16 bytes from the beginning of the record. If a pointer item is not on a 16-byte boundary, a pointer alignment exception is sent to the ILE COBOL program.
Your excerpt explains this, "whichever is smaller". On a 32-bit platform, an int
is 4 bytes. 4 is smaller than 8. So it has a 4-byte alignment.
The pack
pragma causes things to be packed, not unpacked. It won't pad unless it has a reason to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With