Почему GCC не оптимизирует структуры?
Системы требуют, чтобы определенные примитивы были выровнены с определенными точками в памяти (ints к байтам, которые кратно 4, shorts to bytes, кратным 2 и т.д.). Разумеется, они могут быть оптимизированы для удаления наименьшего места в заполнении.
Мой вопрос: почему GCC не делает это автоматически? Является ли более очевидная эвристика (переменные порядка от самого большого требования к размеру до наименьшего), в чем-то не хватает? Является ли какой-то код зависимым от физического упорядочения его структур (это хорошая идея)?
Я только спрашиваю, потому что GCC супер оптимизирован во многих отношениях, но не в этом, и я думаю, что должно быть какое-то относительно прохладное объяснение (к которому я не обращаю внимания).
Ответы
Ответ 1
gcc не упорядочивает элементы структуры, потому что это нарушит стандарт C. Раздел 6.7.2.1 стандарта C99 гласит:
Внутри объекта структуры небитовое поле и единицы, в которых бит-поля имеют адреса, которые увеличиваются в том порядке, в котором они объявлены.
Ответ 2
Структуры часто используются в качестве представлений порядка упаковки форматов двоичных файлов и сетевых протоколов. Это сломалось бы, если бы это было сделано. Кроме того, различные компиляторы будут оптимизировать вещи по-разному, и объединение кода из обоих будет невозможно. Это просто невозможно.
Ответ 3
GCC умнее большинства из нас, производя машинный код из нашего исходного кода; Тем не менее, я дрожу, если умнее нас переустанавливать наши структуры, поскольку это данные, например, могут быть записаны в файл. Структура, которая начинается с 4 символов, а затем имеет целое число в 4 байта, будет бесполезной, если читать в другой системе, где GCC решил, что он должен перенастроить элементы структуры.
Ответ 4
gcc SVN имеет оптимизацию реорганизации структуры (-fipa-struct-reorg), но для этого требуется анализ всей программы и на данный момент не очень мощный.
Ответ 5
Компиляторы C не автоматически упаковывают структуры именно из-за проблем с выравниванием, как вы упоминаете. Доступ не к границам слов (32-бит на большинстве процессоров) несут сильное наказание за x86 и вызывают фатальные ловушки на архитектурах RISC.
Ответ 6
Не сказать, что это хорошая идея, но вы можете, конечно, написать код, который опирается на порядок членов структуры. Например, в качестве хака часто люди бросают указатель на структуру как тип определенного поля внутри, к которому они хотят получить доступ, а затем используют арифметику указателей, чтобы туда добраться. Для меня это довольно опасная идея, но я видел, как она использовалась, особенно в С++, чтобы заставить переменную, которая была объявлена приватной, публично доступной, когда она находится в классе из сторонней библиотеки и не публично инкапсулирована. Переупорядочение членов полностью нарушит это.
Ответ 7
Возможно, вы захотите попробовать последнюю ветку gcc или struct-reorg-branch, которая находится в активной разработке.
https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf