5

根据MSDN,该/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

这有点荒谬不是吗?我是不是误会了?为什么要用这么大的padding,好像很浪费空间。32 位系统上的大多数类型甚至不会使用 64 位,因此大多数变量都会有填充(可能超过 80%)。

4

2 回答 2

10

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

8 的包装意味着它停止尝试对齐大于 8 的成员。这是一个实际限制,内存分配器不会返回对齐优于 8 的地址。如果没有正确对齐并结束,double 非常昂贵跨越高速缓存行。但是如果你写 SIMD 代码就很头疼,它需要 16 字节对齐。

于 2011-12-07T05:14:08.840 回答
3

这并不意味着每个成员都在 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';

这会产生 8, 0, 4- 意味着实际上,int仅填充到 4 字节对齐。

于 2011-12-07T04:55:06.103 回答