为什么在Linux和Windows上使用gcc时,压缩结构的大小会不同?
Why would the size of a packed structure be different on Linux and Windows when using gcc?
在下面的代码中,为什么在Linux和Windows上使用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( "%un", (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字节。为什么会有不同呢?
gcc 4.7.0
这样做是为了与64位msvc++兼容。如果您想正确打包结构,请使用-mno-ms-bitfields
进行编译。(但你的布局将与msvc++不兼容)
第6.37.3节的gcc属性解释了它在ABI规范中的不同,参见这里:http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
属性((packed))是GCC特定于编译器的。因此,该代码甚至无法用msvc++编译。也许你使用了另一种Windows编译器。但是,使用msvc++,您可以这样做:
#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( "%un", (unsigned int)sizeof( header ) );
return 0;
}
这是关于属性和字对齐在内存
看你是否写
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
};
then Linux &Windows都是8
但是当你指定属性以避免默认的世界对齐时,
struct header
{
uint8_t version[ 2 ];
uint8_t flags;
uint32_t size;
} __attribute__((packed));
然后在Linux中因为属性大小变成了7
参见gcc规范中说
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.
更新。最新的MinGW运行良好
g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
和g++ (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
打印样本代码的sizeof()正好等于7字节
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- C++中高效的大型稀疏块压缩线性方程
- 嵌入方指针压缩已禁用
- C++使用整数的压缩数组初始化对象
- 预处理器:插入结构名称中的前一个行号
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 我觉得我放入结构中的输入代码可以压缩,关于如何在保持代码简短的同时保持数据个性化的任何建议?
- 如何在 Node.js 中解压缩 c# 打包结构
- 键:: MAP或类似数据结构中的键压缩
- 使用结构 c++ 读取压缩文件 Gzread
- 正在将压缩结构成员的引用传递给模板.gcc错误
- 位压缩结构
- 对压缩结构成员使用指针时出现编译器警告
- 收到有关压缩结构的意外编译警告
- 读取大部分数据结构以压缩和搜索源代码
- 压缩2D曲线的最佳数据结构/算法是什么?
- 为什么在Linux和Windows上使用gcc时,压缩结构的大小会不同?
- 更改派生类中压缩结构的位大小