问题
In the code below, why is the size of the packed structure different on Linux and Windows when compiled with gcc?
#include <inttypes.h>
#include <cstdio>
// id3 header from an mp3 file
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
} __attribute__((packed));
int main( int argc, char **argv )
{
printf( "%u\n", (unsigned int)sizeof( header ) );
return 0;
}
gcc versions used:
$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
$ x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 4.7.0 20110831 (experimental)
Compile and test:
$ g++ -Wall packed.cpp -o packed && ./packed
7
$ x86_64-w64-mingw32-g++ -Wall packed.cpp -o packed.exe
--> prints '8' when run on Windows.
The Linux binary prints the expected size of 7 bytes, the Windows binary 8 bytes. Why the difference?
回答1:
Section 6.37.3 of the gcc attributes explains it as a difference in ABI specs, see here: http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
回答2:
gcc 4.7.0
does it this way to be compatible with 64-bit MSVC++. If you want to pack the structure properly, compile with -mno-ms-bitfields
. (But then your layout will be incompatible with MSVC++.)
回答3:
The attribute((packed)) is compiler-specific to GCC. Hence, that code won't even compile with MSVC++. Maybe you used another compiler for Windows, though. However, with MSVC++ you could do this:
#include <stdint.h>
#include <cstdio>
// id3 header from an mp3 file
#pragma pack(push,1)
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
};
#pragma pack(pop)
int main( int argc, char **argv )
{
printf( "%u\n", (unsigned int)sizeof( header ) );
return 0;
}
and the struct will be 7 bytes.
回答4:
This is all about attribute and word alignment in memory
see if you write
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
};
then linux & windows both have size 8
but when you specify attribute to avoid default world allignment then
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
} __attribute__((packed));
then in linux because of attritube size becomes 7
see gcc spec says that
If packed is used on a structure, or if bit-fields are used
it may be that the Microsoft ABI packs them differently than
GCC would normally pack them.
回答5:
Update. Latest MinGW works fine.
Both g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
and
g++ (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
prints sizeof() of sample code is exactly equal 7 bytes.
来源:https://stackoverflow.com/questions/7789668/why-would-the-size-of-a-packed-structure-be-different-on-linux-and-windows-when