Вопрос

Системы требуют, чтобы определенные примитивы были выровнены по определенным точкам в памяти (целые числа соответствуют байтам, кратным 4, короткие - байтам, кратным 2, и т.д.).Конечно, они могут быть оптимизированы таким образом, чтобы тратить минимум места на заполнение.

Мой вопрос в том, почему GCC не делает это автоматически?Отсутствует ли каким-либо образом более очевидная эвристика (упорядочивание переменных от требования к наибольшему размеру к наименьшему)?Зависит ли какой-то код от физического порядка его структур (это хорошая идея)?

Я спрашиваю только потому, что GCC супер оптимизирован во многих отношениях, но не в этом, и я думаю, что должно быть какое-то относительно классное объяснение (на которое я не обращаю внимания).

Это было полезно?

Решение

gcc не изменяет порядок элементов структуры, потому что это нарушило бы стандарт C.Раздел 6.7.2.1 стандарта C99 гласит:

Внутри объекта structure элементы, не являющиеся битовыми полями, и блоки, в которых находятся битовые поля , имеют адреса, возрастающие в порядке их объявления.

Другие советы

Структуры часто используются как представления порядка упаковки двоичных форматов файлов и сетевых протоколов.Это сломалось бы, если бы это было сделано.Кроме того, разные компиляторы оптимизировали бы все по-разному, и связывание кода из обоих было бы невозможно.Это просто неосуществимо.

GCC умнее большинства из нас в создании машинного кода на основе нашего исходного кода;тем не менее, я содрогаюсь, если бы он был умнее нас в перестановке наших структур, поскольку это данные, которые, напримерможет быть записан в файл.Структура, которая начинается с 4 символов, а затем имеет 4-байтовое целое число, была бы бесполезна при чтении в другой системе, где GCC решил, что ему следует переупорядочить элементы структуры.

в gcc SVN действительно есть оптимизация реорганизации структуры (-fipa-struct-reorg), но она требует анализа всей программы и на данный момент не очень мощна.

Компиляторы C не упаковывают структуры автоматически именно потому , что из-за проблем с выравниванием, о которых вы упомянули.Доступы вне границ word (32-разрядные на большинстве процессоров) влекут за собой серьезные штрафы на x86 и приводят к фатальным ловушкам на архитектурах RISC.

Не скажу, что это хорошая идея, но вы, безусловно, можете написать код, который зависит от порядка расположения элементов структуры.Например, в качестве взлома часто люди приводят указатель на структуру как тип определенного поля внутри, к которому они хотят получить доступ, а затем используют арифметику указателей, чтобы добраться туда.Для меня это довольно опасная идея, но я видел, как она использовалась, особенно в C ++, чтобы заставить переменную, объявленную закрытой, быть общедоступной, когда она находится в классе из сторонней библиотеки и не инкапсулирована публично.Изменение порядка участников полностью нарушило бы это.

Возможно, вы захотите попробовать последнюю версию gcc trunk или struct-reorg-branch, которая находится в активной разработке.

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top