С ++ выравнивание структуры с выровненными членами

Всегда ли struct выравнивается так же, как член наибольшего выравнивания этой структуры? Если нет, то как это можно обеспечить автоматически, возможно, с помощью расширения, специфичного для gcc? (Я знаю, что есть __attribute((aligned(...)))__, но выравнивание должно быть указано явно).

Отличается ли это поведение между c99, c ++ 99 и c ++ 11? Есть ли в c ++ 11 дополнительные положения для обеспечения выравнивания?

ПРИМЕР. При использовании следующего кода сам Foo будет автоматически выровнен по 8 байтам, или мне также нужно выровнять его явно?

struct Foo{
    int i __attribute__((aligned(8)));
};

person eudoxos    schedule 12.02.2012    source источник
comment
@Basile: Я добавил пример, который должен прояснить ситуацию.   -  person eudoxos    schedule 12.02.2012
comment
Выравнивание составного типа действительно является выравниванием его самого большого члена. Подумайте о массивах таких типов!   -  person Kerrek SB    schedule 12.02.2012
comment
Почему вы беспокоитесь о выравнивании? Компиляторы обычно достаточно хорошо с этим справляются!   -  person Basile Starynkevitch    schedule 12.02.2012
comment
@Basile: я получаю сбои, когда типы, которые должны быть выровнены (математика пакетов), выделяются по невыровненным адресам. (Вы можете с уверенностью предположить, что у меня есть веская причина спросить, когда я спрашиваю)   -  person eudoxos    schedule 12.02.2012
comment
@KerrekSB: не могли бы вы дать ссылку на то, что вы говорите, и пишете в качестве ответа, чтобы я мог принять это? Спасибо!   -  person eudoxos    schedule 12.02.2012
comment
Вы должны были сказать, что используете динамическое размещение. Тогда бремя согласования ложится на функцию распределителя. Соответственно, я улучшил свой ответ.   -  person Basile Starynkevitch    schedule 12.02.2012
comment
@eudoxos: я не думаю, что это прямо в стандарте, но это, по сути, следует из того факта, что каждый член должен быть правильно выровнен, и это должно выполняться даже для массивов составного типа, а массив должен состоять из непрерывного хранилища. Конечно, вы можете просто реализовать это, дополнив каждый тип до sizeof(max_align_t) и просто задав максимальное выравнивание каждого типа, но поскольку более строгие выравнивания удовлетворяют и более слабые, разумно ожидать, что структура будет иметь только максимальное выравнивание. выравнивание среди его членов.   -  person Kerrek SB    schedule 12.02.2012


Ответы (1)


Выравнивание - это свойство системы и процессора. Компилятору разрешено делать все возможное (и он должен знать об ограничениях выравнивания процессора и системы).

Большинство спецификаций ABI (например, AMD64 ABI для Linux) содержат некоторые подсказки по выравниванию.

Я верю, что ограничения выравнивания распространяются от полей к агрегатам (например, struct-s), содержащим их.

Если у вас есть необычные ограничения выравнивания для динамически распределенных данных, вам может потребоваться явное выравнивание, например используя posix_memalign для их размещения. malloc и связанные распределители (включая ::operator new в C ++), вероятно, не будут согласовываться лучше, чем то, что ограничения по умолчанию требуют.

person Basile Starynkevitch    schedule 12.02.2012