C++ MSVC默认内存对齐方式为8

C++ MSVC默认内存对齐方式为8,c++,visual-c++,padding,memory-alignment,C++,Visual C++,Padding,Memory Alignment,根据,/Zp命令默认为8,这意味着使用64位对齐边界。我一直认为,对于32位应用程序,MSVC编译器将使用32位边界。例如: struct Test { char foo; int bar; }; 编译器将按如下方式填充它: struct Test { char foo; char padding[3]; int bar; }; 因此,由于默认情况下使用了/Zp8,这是否意味着使用上面的相同示例,我的填充变为7+4字节: struct Test { cha

根据,
/Zp
命令默认为8,这意味着使用64位对齐边界。我一直认为,对于32位应用程序,MSVC编译器将使用32位边界。例如:

struct Test
{
   char foo;
   int bar;
};
编译器将按如下方式填充它:

struct Test
{
   char foo;
   char padding[3];
   int bar;
};
因此,由于默认情况下使用了
/Zp8
,这是否意味着使用上面的相同示例,我的填充变为7+4字节:

struct Test
{
   char foo;
   char padding1[7];
   int bar;
   char padding2[4];
}; // Structure has 16 bytes, ending on an 8-byte boundary
这有点可笑,不是吗?我误解了吗?为什么要用这么大的填充物,看起来像是浪费空间。32位系统上的大多数类型甚至不会使用64位,因此大多数变量都有填充(可能超过80%)。

这并不意味着每个成员都在8字节边界上对齐。请仔细阅读:

the smaller member type or n-byte boundaries
这里的关键是第一部分-“较小的成员类型”。这意味着结盟程度较低的成员国可能会更不有效地结盟

struct x {
    char c;
    int y;
};
std::cout << sizeof(x);
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n';
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n';
struct x{
字符c;
int-y;
};

这不是它的工作原理。成员按其大小的倍数对齐。Char到1字节,short到2,int到4,double到8。该结构在末端填充,以确保在数组中使用该结构时,成员仍然正确对齐


填料为8表示它停止尝试对齐大于8的构件。这是一个实际限制,内存分配器返回的地址对齐度不超过8。如果double没有正确对齐,并且最终跨越缓存线,那么它的成本将非常昂贵。但是,如果您编写SIMD代码,它需要16字节对齐,这是一个令人头痛的问题。

您能澄清一下
7+4
吗?我现在有点被这个问题弄糊涂了。@Mysticial:我用另一个例子更新了我的OP,让你明白我的意思。很抱歉造成混淆。感谢您的澄清。我刚刚测试了第一个结构,大小只有8字节,通过第二个结构片段填充。所以我无法重新解释你得到了什么。(或者至少是你认为你应该得到的)你答案的最后一部分是错误的。从结构中删除int,注意sizeof()不返回8。那么,根据MSDN,默认对齐方式是8,那么我的OP中的最后一个代码段就是对齐填充的样子?如果没有,请解释。@Robert:你最后的代码是错误的。它将像这样填充
char-foo;pad[3];int-barint
是结构中最大的成员。你应该仔细阅读汉斯说的话