Заполнение памяти компилятора с ++: должны ли объекты иметь одинаковый размер?

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

Теперь, насколько я понимаю, если компилятор собирается «дополнить» каждый меньший тип данных до размера самого большого, почему объекты просто не стандартизированы для одного типа данных? (Самый большой)


person bigcodeszzer    schedule 17.11.2015    source источник
comment
Заполнение структуры данных   -  person crashmstr    schedule 17.11.2015
comment
очевидно, длина заполнения эквивалентна самому большому типу данных - откуда вы взяли эту идею?   -  person davmac    schedule 17.11.2015
comment
Единственная идея, если вы знаете максимальный размер объекта, попробуйте установить выравнивание по структуре, где все объекты хранятся до этого размера, gcc: __attribute__ ((aligned (40))) будет выравнивать объекты по каждые 40 байтов.   -  person vlk    schedule 17.11.2015
comment
почему объекты просто не стандартизированы для одного типа данных - не будет ли неприятно, если char x[20]; фактически выделит 320 байт? А приходилось писать x += 16; вместо x++?   -  person M.M    schedule 17.11.2015


Ответы (1)


Обычно компиляторы вставляют отступы для выравнивания элементов по границам, которые соответствуют их размеру. Здесь между a и b будет вставлено 16-битное заполнение, чтобы гарантировать, что b выровнен по 32-битному.

int16_t a;
/* 16 bits of padding */
int32_t b;

Но если члены структуры естественным образом заполняют это пространство, вставлять отступы не нужно. Здесь каждый член уже выровнен: a и b выровнены по 16 бит, а c выровнены по 32 бита.

int16_t a;
int16_t b;
int32_t c;

Стандартизация каждой переменной до 32-битной приведет к потере места.

Точно так же у вас может быть сочетание разных размеров. Добавление небольшого количества отступов более эффективно, чем расширение всех переменных до большого единообразного размера.

int8_t a;
/* 8 bits of padding */
int16_t b;
int32_t c;
person John Kugelman    schedule 17.11.2015
comment
Я думаю, что меня интересует, почему язык С ++ не применяет объектные ограничения? Я имею в виду, если в объекте 17 бит, а затем будет вставлено 15 бит, не должен ли компилятор это уловить? - person bigcodeszzer; 18.11.2015
comment
Я не уверен, что понимаю вопрос. Что ты имеешь в виду, поймай это? Вы имеете в виду выдать ошибку, если будет вставлено дополнение? Для программиста не является ошибкой написать структуру, требующую заполнения. Отступы не являются признаком проблемы, которую необходимо исправить, если вы об этом спрашиваете. - person John Kugelman; 18.11.2015
comment
Я имею в виду ограничение дизайна. На каком-то уровне объекты - это контейнеры, в которых хранятся все данные программы. Если объекты создают «отступы», не выравниваясь должным образом, не следует ли «остаточные» данные (каждого объекта) помещать в другой объект? - person bigcodeszzer; 18.11.2015
comment
Я согласен, обычно заполнение не считается ошибкой, но если вы генерируете сотни или даже тысячи объектов, и каждый из них заполняет так много бит, разве это не форма утечки памяти? - person bigcodeszzer; 18.11.2015
comment
Да, это пустая трата места. Компилятор не заставляет вас писать эффективные программы. Если использование памяти вызывает беспокойство, программист должен изменить структуру структуры более эффективным образом. Учтите, что это не всегда возможно. Возьмем первый пример. Невозможно избежать 16-битного заполнения. Если вы поменяете местами int16_t a и int32_t b, отступ будет перемещен из середины в конец. Если у вас есть массив этих структур, компилятор захочет выровнять каждую копию int32_t b. Он не создаст 48-битную структуру. Он так или иначе добавит отступы. - person John Kugelman; 18.11.2015
comment
Ага. Кажется, что-то, что будет обрабатываться на стороне компилятора, понимаете? Как объект типа сборщика мусора, который извлекает все «лишние» биты и объединяет их в выровненный объект мусора. Вы знаете, выполняет ли Java также выравнивание битов? - person bigcodeszzer; 18.11.2015
comment
Это хороший вопрос. Почему бы тебе не исследовать это? Если вы не можете найти ответ, я рекомендую вам задать здесь еще один вопрос. Я не могу дать ответ в комментарии. - person John Kugelman; 18.11.2015
comment
stackoverflow .com / questions / 33790934 / - person bigcodeszzer; 19.11.2015