sizeof() 在 32 位和 64 位进程之间的行为不同

sizeof() behaving differently between 32 bit and 64 bit processes

本文关键字:之间 进程 位和 sizeof      更新时间:2023-10-16

考虑以下程序

#include<iostream>
struct SimpleStructure
{
double obj;
};
struct Composite
{
struct SimpleStructure u;
char ch;
};
int main()
{
using namespace std;
cout << "sizeof(double)                 : " << sizeof(double) << endl;
cout << "sizeof(struct SimpleStructure) : " << sizeof(struct SimpleStructure) << endl;
cout << "sizeof(struct Composite)       : " << sizeof(struct Composite) << endl;
return 0;
}

当我用g++ -m64 <filename>.cpp编译上述内容时,我得到以下输出

sizeof(double)                 : 8
sizeof(struct SimpleStructure) : 8
sizeof(struct Composite)       : 16

但是当我使用g++ -m32 <filename>.cpp编译时相同的代码,我得到以下输出

sizeof(double)                 : 8
sizeof(struct SimpleStructure) : 8
sizeof(struct Composite)       : 12

为什么在 32 位和 64 位进程中结构中的填充存在差异?

在 32 位平台上alignof(double) == 4.请参阅man gcc

-malign-double
-mno-align-double
Control whether GCC aligns "double", "long double", and "long long"
variables on a two-word boundary or a one-word boundary.  Aligning
"double" variables on a two-word boundary produces code that runs
somewhat faster on a Pentium at the expense of more memory.
On x86-64, -malign-double is enabled by default.
Warning: if you use the -malign-double switch, structures
containing the above types are aligned differently than the
published application binary interface specifications for the
x86-32 and are not binary compatible with structures in code
compiled without that switch.

结构的大小是具有最大对齐要求的杆件对齐的倍数。这里,这样的成员是double型的,所以sizeof(struct Composite) == N * alignof(double)

就C标准而言,编译器可以自由选择任何对齐方式。以下是关于我使用的编译器如何实现对齐的说明。

通常,选择字大小(32 位系统上为 32 位,64 位系统上为 64 位),因为就目标平台上的内存使用量和性能之间的权衡而言,它通常是一个有效的选择。通常,内存可以在字大小的块中访问,并且CPU指令假定数据已对齐,因此如果数据未对齐,CPU将需要访问2个内存块并将数据转换为对齐状态。这会浪费宝贵的 CPU 周期。

小于字大小的实体按其大小对齐。单词大小和较大的实体在单词边界上对齐。

结构成员单独对齐,然后填充整个结构并与其最大成员相同。

默认对齐方式通常可以用杂注覆盖。有关详细信息,请参阅编译器的文档。

例:

/* Override the default alignment and pack everything tight. */
#pragma pack(1)

首先,整数类型的大小可能因体系结构而异。这里有一张漂亮的桌子:http://en.cppreference.com/w/cpp/language/types

其次,指针的大小因体系结构而异。 32 位计算机具有 32 位指针,64 位计算机具有 64 位指针。如果你对较旧的架构感兴趣,8 位机器有 16 位指针,16 位机器有 32 位指针,尽管它们在 8086 上工作得很奇怪。

最后,您的结构中的情况可能是对齐。出于效率原因,变量与字边界对齐,并且字大小可能因体系结构而异。在此处查看更多信息:http://en.cppreference.com/w/cpp/language/object#Alignment