Подтвердить что ты не робот

Используйте __attribute __ ((aligned())) в struct, почему результат sizeof это?

Это мой тестовый код:

#include <cstdio>
struct A {
    int  a;
    int  b;
    int  c __attribute__((aligned(4096)));
    int  d;
}t;
int main()
{
    printf("%d\n",sizeof(t));

    return  0;
}

Результат - 8192, но я не могу понять причину.

4b9b3361

Ответ 1

Есть несколько фактов о выравнивании в структурах, которые стоит упомянуть:

  • Размер типа всегда кратен его выравниванию.
  • Выравнивание структуры всегда кратно выравниванию всех ее членов.

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

Но так как для него требуется прокладка 4080 байт до c, размер структуры составляет не менее 4104, но должен быть мультиплекс 4096, его выравнивание. Так оно растет до 8192.

Ответ 2

Это потому, что sizeof указывает, где будет размещаться следующий элемент в массиве. То есть, если у вас есть объявление

struct A a[2];

Вам нужно, чтобы оба a[0].c и a[1].c были выровнены в 4096 байтах.

Собственно говоря, компилятор мог бы сделать это с размером 4096, но это не связано с тем, что struct A наследует требование выравнивания и ставит два int перед полем .c, которое тоже должен быть выровнен, который вставляет 4080 ish байты заполнения между .b и .c, а затем 4080 ish байты заполнения после .d.

То, как это сделал компилятор , (без изменения элементов структуры), заключается в расширении концепции выравнивания. Вместо того, чтобы просто требовать, чтобы адрес попадал на адрес формы N*4096, он мог расширять его со смещением, требующим, чтобы он упал на адрес формы N*4096-2*sizeof(int). Предоставление struct A такого требования приведет к тому, что элемент .c, естественно, станет 4096 байт, выровненным без необходимости заполнения между .b и .c (тоже).