Почему GCC не оптимизирует структуры?
-
02-07-2019 - |
Вопрос
Системы требуют, чтобы определенные примитивы были выровнены по определенным точкам в памяти (целые числа соответствуют байтам, кратным 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, которая находится в активной разработке.