2017-02-14 6 views
1

Я читаю книгу о разработке и реализации компилятора. В части, посвященной управлению хранением, автор пишет функцию выделения памяти. Он хочет, чтобы функция была соответствующим образом выровнена для любого типа. Он утверждает, что размер союза ниже - минимальное выравнивание на главной машине. Я не совсем понимаю, что это значит. Из книги: «... ее поля - это те, которые, скорее всего, будут иметь самые строгие требования к выравниванию».Минимальные требования к выравниванию для машины

union align { 
    long l; 
    char *p; 
    double d; 
    int (*f) (void); 
}; 

Может кто-нибудь объяснить, что означает «строгие требования выравнивания» и как это дает минимальное выравнивание на хост-машине?

ответ

4

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

Таким образом, в этом смысле, union align будет иметь такое же выравнивание либо как l, p, d или f (в зависимости от того имеет наибольшие требования выравнивания).

Например, если f элемента, который имеет типа int (*)(void) имеет требование выравнивания 8, весь союз будет выровнен по границе 8 байт, даже если long требуется только 4.

Я не совсем уверен, гарантирует ли стандарт, что наибольшее соответствие требованиям этих четырех типов будет «минимальным выравниванием на главной машине». Это может быть просто хорошим упражнением, чтобы понять, как работает компилятор в отношении управления хранилищами.

3

Рассмотрите машину, которая из-за ограничений шины памяти может читать 16-битные значения только с четных адресов.

16-битное значение на такой машине будет иметь «требование выравнивания» из 2.

ли не полагаться на union обману. Так как C11, есть:

  • max_align_t который является синонимом самого большого (стандартного) скалярного типа для платформы (1), то есть тип с выравниванием по обслуживаемой malloc().
  • _Alignof, который дает требования к выравниванию для данного типа.
  • alignas, что позволяет изменять выравнивание типов.

(1): Самый большой такой тип будет обычно быть long double, тип подозрительно отсутствует из примера вашей книги ...

Обратите внимание, что компилятор может поддерживать «расширение» типа, которые требуют специальной обработки , Например, имея 256-байтовый тип данных SSE, но имеющий malloc(), «только» выполняет выравнивание по 128 байт.

Смежные вопросы