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

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

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

    return  0;
}

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

2 ответов


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

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

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

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


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

struct A a[2];

вам понадобятся оба a[0].c и a[1].c выравниваться по 4096 байт.

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

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