alignas в структурах на 32-битных платформах

Я получаю неожиданные результаты при запуске следующего кода для 32-разрядного Linux x86 (флаги компилятора: g ++ -std = c ++ 14 -m32). Я попробовал GCC и Clang.

#include <iostream>
using namespace std;

struct S1
{
uint64_t a;
uint32_t b;
};

struct S2
{
alignas(uint64_t) char a[8];
uint32_t b;
};

int main()
{
cout << "sizeof(S1)=" << sizeof(S1) << endl;
cout << "sizeof(S2)=" << sizeof(S2) << endl;
}

Выход:

sizeof(S1)=12
sizeof(S2)=16

Что здесь происходит? Почему S1 и S2 имеют разные размеры? Насколько я понимаю, 64-разрядные целочисленные значения выровнены по 32-разрядным на 32-разрядных компьютерах с архитектурой x86. Это объясняет, почему размер S1 составляет 12 байтов. Но почему это не относится к S2?

8

Решение

alignof ключевое слово измеряет выравнивание типа как законченного объекта; то есть когда он выделен как отдельный объект или элемент массива. Это не обязательно совпадает с требованиями выравнивания этого типа в качестве подобъекта; Гарантируется ли выравнивание элементов POD-структуры или стандартного типа макета в соответствии с их требованиями к выравниванию?

Выравнивание 64-битного целого числа в структуре предписывается ABI x386 в 4 байта; gcc не вправе изменять это, так как это нарушит бинарную совместимость с другими объектными файлами и программами. Однако он может выровнять целые 64-битные целые объекты в 8 байтов, поскольку это не влияет на ABI и обеспечивает более эффективный доступ к памяти.

4

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

Других решений пока нет …