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

Может ли обертывание типа в структуре вызвать дополнительное заполнение?

Возможный дубликат:
Размер структуры с одним элементом

Для любого типа A и следующей структуры:

struct S
{
    A a;
};

Существуют ли случаи, когда sizeof(S) больше, чем sizeof(A)?

Например, может sizeof(std::array<T, n>) быть больше sizeof(T[n])?

4b9b3361

Ответ 1

В то время как структура может быть дополнена, во всех системах, которые я знаю, компилятор будет прокладывать так, чтобы выравнивание структуры было таким же, как и наибольшее выравнивание ее членов. Он делает это так, чтобы массив структуры всегда был правильно выровнен.

Итак:

struct S 
{
   char a;
} // Size 1, no padding

struct S2 
{
   unsigned int a;
   char b;
} // Size 8, 3 bytes padding (assuming 32 bit integer)

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

В стандарте C/С++ не указывается ни одна из этих деталей. Вы хотите использовать C ABI (двоичный интерфейс приложения) для системы, на которой вы работаете, которая должна указывать макет по умолчанию для structs (компиляторы могут выбрать переопределение, если они сочтут нужным, см. Также пакет #pragma). Например, посмотрите X86_64 ABI стр. 13, в котором говорится:

Агрегаты и союзы Структуры и союзы предполагают выравнивание их наиболее строго выровненная составляющая. Каждому члену присваивается самое низкое доступное смещение с соответствующим выравниванием. Размер любого объекта всегда кратно выравниванию объекта. Массив использует то же выравнивание, что и его элементы, за исключением того, что локальный или глобальный переменная массива длиной не менее 16 байтов или переменная длина C99 массив всегда имеет выравнивание не менее 16 байт. Состав и объекты объединения могут потребовать заполнения для соответствия размерам и выравниванию ограничения. Содержимое любого дополнения не определено.

Ответ 2

Возможность использовать A внутри S означает, что компилятор уже знает структуру A и уже добавил к нему байты заполнения. Я не вижу причин для добавления дополнительного дополнения к S, поскольку он уже выровнен.

Ответ 3

Соответствующий текст - 5.3.3/2 "При применении к классу результатом является количество байтов в объекте этого класса, включая любое дополнение, необходимое для размещения объектов этого типа в массиве".

Реализации разрешено добавлять дополнительные байты для целей проверок привязки к массиву (например, "this is the 5th array member out of a total of 12", поскольку это находится в пределах предоставленной здесь возможности и явно не запрещается любым другим требованием.

(Предположительно, эта реализация также сохранит указание "1 из 1" для структур, которые не являются частью массива; в С++ типы S и S[1] вполне взаимозаменяемы)

Ответ 4

ISO/IEC 14882 (10/2008) 1.8.5:

Если это не бит-поле (9.6), наиболее производный объект должен иметь ненулевой размер и должен занимать один или несколько байт памяти. Субобъекты базового класса могут иметь нулевой размер.

Это означает, что пустая структура имеет размер 1, хотя размер "всех членов данных" (их нет) равен нулю, равно как и битовое поле нулевой длины (согласно 9.6.2 это должно быть неназванное битовое поле).
Ни один из них не применяется, поскольку вы не запрашивали пустую структуру, а ваш член назван (поэтому он не может быть нулевой длины).

Аналогично было бы верно, если ваш член a имел тип void, но 3.9.5 не позволяет этого ( "[...] типы пустот являются неполными типами (3.9.1). Объекты не должны быть определены как неполные типы" ).

Короче говоря, как вы сказали, вас больше всего интересует, что говорит стандарт: нет, стандарт явно не определяет такой случай.

Однако он также не запрещает компилятору добавлять дополнения или применять выравнивание, и большинство компиляторов будут по умолчанию компоновать/выравнивать структуры до размера машинного слова (если явно не указано иначе).

Ответ 5

Если A является байтом, то структура будет выровняться с ближайшей границей. Скорее, если A меньше границы, то да, оно будет больше. EX структура RGB имеет тот же размер, что и структура RGBA.

У меня нет образца кода, который сделает это. Вы должны сбрасывать память и видеть отверстия. Если вы затем предположите, что все выровнены по размеру и нарисовали структуру на пачке памяти, у вас будут плохие данные. Вот почему WAD имеют отступы для выравнивания. По мере усложнения композиций способность закрывать дыры компилятором уменьшается. В конце концов будет добавлено дополнение, и любые предположения о макете памяти будут становиться все более и более неправильными.

Ответ 6

Структура может быть дополнена (это позволяет компиляторам делать что угодно, например, заполнять шести октетный тип до восьми, чтобы выравнивать границы страниц). Это вряд ли произойдет.

std:: array будет больше, поскольку он хранит некоторую дополнительную информацию в классе, например длину массива. Ввод текста на автопилоте; прочитайте std::vector без размышлений.