Типы выравнивания по умолчанию в Visual C ++ - PullRequest
0 голосов
/ 16 февраля 2011

Только что заметил что-то странное для меня. Visual C ++ по умолчанию не выравнивает объект в требуемой границе. Например, long long выравнивается по границе 4 байта, а __alignof (T) возвращает 8 (насколько я вижу, он всегда возвращает размер типа). Похоже, что он не выровнен должным образом. Например

long long a1;
char g;
long long a2;
// alignment check for &a2 fails
if (((uintptr_t)&a2 & (__alignof(long long) - 1)) != 0) // failed

Я также пытался просто напечатать указатель, значение &a2 равно 0x0035F8FC (3537148 в декабре).

Есть ли что-то, что я ошибаюсь? Мне нужен правильно выровненный объект типа long long. Что я могу с этим поделать? Я мог бы использовать __declspec(align()) расширение Microsoft, но оно требует буквального числа, поэтому я не могу написать ничего подобного.

__declspec(align(__alignof(long long))) long long object;

Ответы [ 2 ]

1 голос
/ 16 февраля 2011

VC не гарантирует автоматического выравнивания стека переменных, самое большее переменная будет выровнена с выравниванием стеков (обычно 4 байта в 32-битных системах).Если вам нужно специальное выравнивание, вам нужно использовать __declspec(align(x)), точно так же, как типы SSE MSVC (например, __m128), в противном случае вам нужно будет использовать _aligned_malloc вместо

0 голосов
/ 16 февраля 2011

Выравнивание должно минимизировать циклы памяти при доступе к ОЗУ. 4-байтовое выравнивание использует только два 32-битных доступа к long long. Восьмибайтовое выравнивание не улучшает поведение. Компилятор имеет выравнивание по умолчанию, которое можно перезаписать с помощью параметра /Zp.

См. Также: Свойства конфигурации C / C ++ Aligment элемента структуры генерации кода.

...