Как работает ' declspec (align (#))`?

да, Я есть прочитайте это:http://msdn.microsoft.com/en-us/library/83ythb65.aspx Но мне это непонятно. Прежде всего,__declspec(align(#)) делает каждый объект (в структуре), объявленный с ним, начальным с выровненного смещения. Это понятно. Aligment также "наследуется" структурированным объектом. Но это не меняет размер объекта, не так ли? Именно, почему sizeof() в этом коде:

__declspec(align(32)) struct aType {int a; int b;};
sizeof(aType);

вернуться 32?

2 ответов


размер объекта используется для расчета смещения в массивах и при использовании указателей, поэтому 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; 

не будет работать правильно, так как компилятор будет умножать 12 by sizeof(aPtr) добавить aPtr внутренне.


документация либо плохо написана, либо мое владение английским как иностранным языком не соответствует ей.

// 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);

на __declspec(align(#)) влияет только на выравнивание структуры и sizeof(), не каждый из членов в нем. Если вы хотите, чтобы каждое свойство было выровнено, необходимо указать выравнивание на уровне элемента.

Я также изначально предполагал, что a struct-level __declspec(align()) влияет на него, и это члены, но это не так. Так что если вы хотите в выравнивание членов, вы должны быть конкретными.