为什么使用 gcc 时,Linux 和 Windows 上打包结构的大小会不同?
在下面的代码中,为什么使用 gcc 编译时,Linux 和 Windows 上的打包结构的大小不同?
#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 版本:
$ 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)
编译和测试:
$ 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.
Linux 二进制文件打印预期大小 7 字节,Windows 二进制文件打印 8 字节。为什么有区别?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
gcc 4.7.0
这样做是为了与 64 位 MSVC++ 兼容。如果要正确打包结构,请使用-mno-ms-bitfields
进行编译。 (但是这样你的布局将与 MSVC++ 不兼容。)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++.)gcc 属性的第 6.37.3 节将其解释为 ABI 规范中的差异,请参见此处: http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
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
属性((packed)) 是 GCC 特定于编译器的。
因此,该代码甚至无法使用 MSVC++ 进行编译。不过,也许您使用了另一个 Windows 编译器。然而,使用 MSVC++ 你可以这样做:
并且结构将是 7 个字节。
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:
and the struct will be 7 bytes.
这都是关于内存中的属性和单词对齐,
看看你是否写了
然后linux & 。 Windows 的大小都是 8,
但是当您指定属性以避免默认世界对齐时,那么
在 linux 中,由于 attritube 大小变为 7
请参阅 gcc 规范说明
This is all about attribute and word alignment in memory
see if you write
then linux & windows both have size 8
but when you specify attribute to avoid default world allignment then
then in linux because of attritube size becomes 7
see gcc spec says that
更新。最新的 MinGW 工作正常。
g++(i686-win32-dwarf-rev0,由 MinGW-W64 项目构建)8.1.0
和g++(x86_64-win32-seh-rev0,由 MinGW-W64 项目构建)8.1.0
打印示例代码的 sizeof() 正好等于 7 个字节。
Update. Latest MinGW works fine.
Both
g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
andg++ (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
prints sizeof() of sample code is exactly equal 7 bytes.