Reputation: 13
#include "stdio.h"
#pragma pack(8)
struct testSize {
int a; //size 4, alignment 8
double b;//size 8, alignment 8
};
#pragma pack()
int main(int argc, char** argv)
{
printf("sizeof testSize %d \n", sizeof(struct testSize));
printf("sizeof int %d , sizeof double %d\n", sizeof(int), sizeof(double));
return 0;
}
The default max alignment of a struct is 8, and also we can set by #pragma pack(8)
or -fpack-struct=8
. But on 32bit process compiled with gcc, it doesn't work.
On Linux (32):
$ gcc -m32 -fpack-struct=8 -o TestSize TestSize.c
$ ./TestSize
sizeof testSize 12
sizeof int 4 , sizeof double 8
On VS (x86):
sizeof testSize 16
sizeof int 4 , sizeof double 8
On linux, the alignment seems like 4, not 8. From the doc, it's "For compatibility with Microsoft Windows compilers".
Upvotes: 0
Views: 168
Reputation: 180361
The documentation and observed behavior of GCC are consistent with each other.
For compatibility with Microsoft Windows compilers, GCC supports a set of #pragma directives that change the maximum alignment of members of structures
[...]
#pragma pack(n) simply sets the new [maximum] alignment
The resulting size of the struct shows that GCC on Linux is aligning the double
on a four-byte (or less) boundary. Four is less than 8.
The documentation and observed behavior of VS are consistent with each other.
Specifies packing alignment for structure, union, and class members.
[...]
n
[...] The alignment of a member will be on a boundary that is either a multiple ofn
or a multiple of the size of the member, whichever is smaller.
The size of a double
is 8, and the specified maximum alignment is 8. The size of the structure shows that VS on Windows aligns the double on an 8-byte boundary, just as it should.
On linux, the alignment seems like 4, not 8. From the doc, it's "For compatibility with Microsoft Windows compilers".
Both compilers accept your pragma. It has no practical effect on either one. This is source compatibility with respect to the pragma.
That the default alignment rules for the two compilers differ could be taken as an incompatibility, but that's not an issue of the pragma. And in this case you can use the pragma to get the same (weaker) alignment of both structures by specifying maximum alignment 4. Or you should be able to get the stronger alignment with GCC on x86 Linux by via the -malign-double
compiler option.
But note well that by looking at VS on Windows and GCC on Linux, you are comparing apples and oranges. There is no binary compatibility consideration across those platforms. Consider trying your experiment with a Windows build of GCC, such as MinGW's. I'm not in a position to test at the moment, but I anticipate that GCC on Windows will conform to Windows alignment conventions by default, and that pragma pack
will affect the layout exactly the same way on the GCC/Windows as it does on VS/Windows.
Upvotes: 0
Reputation: 71018
The GCC page you link says the pragma "changes the maximum alignment". It could well be that the 8
bytes you specify is being ignored in favor of a smaller default of 4 on your compilation target.
(Packing pragmas are typically used when it's desirable to "pack tight", like to single-byte alignment, for structures that will travel over the wire or get persisted to disk in a program-agnostic sort of way. They're not generally used to enforce arbitrary alignments.)
Upvotes: 2