I am trying to align data members by using #pragma pack (n)
. Take the following as an example:
#include <iostream>
using namespace std;
#pragma pack(8) // or (16)
struct A
{
int a;
char b;
char c;
char d;
char e;
char f;
double g;
};
int main()
{
cout << sizeof(A) << endl;
return 0;
}
Both will print 24
for #pragma pack(8)
and #pragma pack(16)
. I can understand the result for n=8
with the data alignment, of my understanding, as follows:
Bytes: |1 2 3 4|5|6|7|8|9|10 11 12 13 14 15 16|17 18 19 20 21 22 23 24|
Data: |a |b|c|d|e|f|padding |g |
But I cannot understand why the result is still 24
for n=16
. I also tried other examples, all of them seems to give same result for n=8
and n=16
. Can someone explain why? Are the data members aligned the same way as n=8
?
P.S.: Tested in VS2010 under Win-x64.
From the page you linked to:
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.
For each member it takes the minimum alignment, between the member's optimal alignment and the pack value. The members in your example are aligned exactly the same regardless of pack(8)
and pack(16)
because the optimal alignment of the types are all less than 16.
If you had a member that required 16-byte alignment, such as __m128
, you would be able to find different results.
For pack
to mean much, the struct in question must contain a member at least as large as the N
you specify to the pragma. For example:
#include <iostream>
using namespace std;
#pragma pack(push)
#pragma pack(1)
struct A
{
char a;
double b;
};
#pragma pack(8)
struct B
{
char a;
double b;
};
#pragma pack(pop)
int main()
{
cout << sizeof(A) << "\n" << sizeof(B) << endl;
return 0;
}
On my computer, this prints:
9
16
...which I'd consider fairly typical (at least for machines that accept pragma pack
in the first place).
Because pack specifies the maximum alignment used when needed. Values smaller then 16 bytes will still be aligned to smaller values because there is no gain in aligning them to larger values. SO an 32-bits integer is still aligned to 4 byes. A double is aligned to 8 bytes. SO you probably would see a difference when switching between 4 and 8.