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?
The only possibility that initially springs to mind, where they could be packed, is if char and int were the same size, so that the minimum size of the char/int/char structure would allow for no padding, ditto for the int/char structure. However, that would require both sizeof (int) and sizeof (char) to be four (to get the twelve and eight sizes).
The different file structure which uses different the size of space for storaging files. The windows os uses NTFS partition and The linux os uses ext3 or ext4 partition. so you can find that the same file shows different sizes in different operating systems.
It must be taken in consideration that some processors such as the ARM Cortex-M0 do not allow unaligned memory access; in such cases, structure packing can lead to undefined behaviour and can crash the CPU.
The windows os uses NTFS partition and The linux os uses ext3 or ext4 partition. so you can find that the same file shows different sizes in different operating systems. Thanks for contributing an answer to Ask Ubuntu!
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++.)
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
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.
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