Как работает __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?

6

Решение

Размер объекта используется для расчета смещений в массивах и при использовании указателей, поэтому sizeof(x) всегда должен быть кратным значению выравнивания. В этом случае 1 х 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 от sizeof(aPtr) добавить к aPtr внутренне.

12

Другие решения

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

// 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()НЕ каждый из членов в нем. Если вы хотите, чтобы каждое свойство было выровнено, вам нужно указать выравнивание на уровне элемента.

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

3

По вопросам рекламы [email protected]