`__declspec(align(#))`如何工作?

NPS*_*NPS 6 c++ sizeof alignment visual-studio-2010 declspec

是的,我已经阅读:http://msdn.microsoft.com/en-us/library/83ythb65.aspx 但它不是我清楚.首先,__declspec(align(#))使用它声明的每个对象(在一个结构中)以对齐的偏移量开始.那部分很清楚.该对象也是由对象所在的结构化"继承"的.但它不会改变对象的大小,是吗?确切地说,为什么sizeof()在这段代码中:

__declspec(align(32)) struct aType {int a; int b;};
sizeof(aType);
Run Code Online (Sandbox Code Playgroud)

回来32

Mat*_*son 12

对象的大小用于计算数组中的偏移量,当您使用指针时,因此sizeof(x)必须始终是对齐值的倍数.在这种情况下,1 x 32.但如果你有__declspec(align(32)) struct aType {int a[12]; };,那么尺寸将是2 x 32 = 64,因为sizeof(a)是12 x 4 = 48.如果我们改变它以对齐到4,8或16,它将是48.

它实际工作的方式是编译器在结构的命名成员之后添加一个未命名的填充成员,以将结构填充到它的对齐大小.

如果它不能以这种方式工作,例如:

 aType *aPtr = new aType[15]; 

 aPtr[12].a = 42; 
Run Code Online (Sandbox Code Playgroud)

不工作的权利,因为编译器将成倍12sizeof(aPtr)添加到aPtr内部.

  • 是的,`struct`现在是32个字节长.例如,用于两个整数的8个字节和这些字节中的24个是"填充"以填充阵列中的第一和第二aType对象之间的空白空间. (2认同)

Cod*_*gry 6

文档要么写得不好,要么我的英语作为外语的水平达不到它的水平。

// make a nice 16 align macro
#ifndef ALIGN16
#define ALIGN16 __declspec(align(16))
#endif

// align the structure
struct ALIGN16 CB {
    ALIGN16 bool m1; // and
    ALIGN16 int m2; // align
    ALIGN16 int m3; // each
    ALIGN16 short m4; // element
};

// now it performs as expected
printf("sizeof(CB) %d\r\n", sizeof(CB));
CB vCb;
printf("CB: %p, %%%d\r\n", &vCb, (UINT_PTR)&vCb % 16);
printf("CB.m1: %p, %%%d\r\n", &vCb.m1, (UINT_PTR)&vCb.m1 % 16);
printf("CB.m2: %p, %%%d\r\n", &vCb.m2, (UINT_PTR)&vCb.m2 % 16);
printf("CB.m3: %p, %%%d\r\n", &vCb.m3, (UINT_PTR)&vCb.m3 % 16);
printf("CB.m4: %p, %%%d\r\n", &vCb.m4, (UINT_PTR)&vCb.m4 % 16);
Run Code Online (Sandbox Code Playgroud)

__declspec(align(#))仅影响该结构的取向和sizeof(),而不是每个成员在其中。如果希望每个属性都对齐,则需要在成员级别指定对齐方式。

我最初还假设 astruct-level __declspec(align())会影响它及其成员,但它不会。因此,如果您希望每个成员对齐,则需要具体。