Оптимизируются ли неиспользуемые функции? - PullRequest
48 голосов
/ 02 июня 2011

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

Ответы [ 9 ]

26 голосов
/ 02 июня 2011

Это зависит от компилятора. Visual C ++ 9 может это сделать - неиспользуемые static функции удаляются на этапе компиляции (для этого даже есть предупреждение C4505 ), неиспользуемые функции с внешним связыванием могут быть удалены на этапе компоновки в зависимости от компоновщика настройки .

21 голосов
/ 02 июня 2011

MSVC (компилятор / компоновщик Visual Studio) может сделать это, если вы компилируете с /Gy и связываете с /OPT:REF.

GCC / binutilsможет сделать это, если вы компилируете с -ffunction-sections -fdata-sections и связываете с --gc-sections.

Не знаете о других компиляторах.

16 голосов
/ 04 июня 2011

Как правило, ответом является:

Да: для неиспользуемых static функций.

Нет: для неиспользованных глобальнодоступные функции.

Компилятор не знает, ссылается ли на него какой-либо другой модуль компиляции.Кроме того, большинство типов объектных модулей не позволяют удалять функции после компиляции, а также не дают возможность компоновщику определить, существуют ли внутренние ссылки.(Линкер может определить, существуют ли внешние .) Некоторые линкеры могут это сделать, но многие вещи работают против этого.

Конечно, функция в своем собственном модуле не будет загруженабез необходимости любым компоновщиком, если только он не является частью общей библиотеки.(Потому что на него можно ссылаться в будущем во время выполнения, очевидно.)

5 голосов
/ 02 июня 2011

Многие компиляторы делают, но это зависит от конкретной реализации.Сборки отладки часто включают в себя все функции, чтобы их можно было вызывать или исследовать из отладчика.Многие компиляторы встроенных систем, по причинам, которые я не совсем понимаю (*), будут включать все функции в объектный файл, если они есть, но будут полностью исключать любые объектные файлы, которые вообще не используются.

Обратите внимание, что в языках, которые поддерживают Reflection (например, Java, C #, vb.net и т. Д.), Возможно, учитывая имя функции, создать ссылку на нее во время выполнения, даже если в коде нет ссылок.Например, подпрограмма может принять строку из консоли, изменить ее каким-либо образом и сгенерировать вызов функции с этим именем.У компилятора или компоновщика не будет возможности узнать, какие имена могут быть сгенерированы, и, следовательно, нет способа узнать, какие функции можно безопасно исключить из кода.Однако в C или C ++ такой трудности не существует, поскольку в коде нет определенного способа создания ссылки на функцию, переменную или константу без явной ссылки, существующей в коде.Некоторые реализации могут упорядочить вещи так, чтобы последовательно объявленные константы или переменные были сохранены последовательно, и, таким образом, можно создать ссылку на объявленную позже, добавив смещение к ранее объявленному, но поведение таких приемов явноне гарантируется стандартами C или C ++.

(*) Я понимаю, что это облегчает компиляцию и компоновку, но на современных компьютерах не должно возникнуть никаких проблем с запуском более сложных алгоритмов компиляции и компоновки, чем это было бы практично в последние десятилетия,Если ничего другого, то метод двухпроходной предварительной компиляции / предварительной ссылки / компиляции / ссылки может на этапе предварительной компиляции / ссылки создать список используемых вещей, а затем на «реальной» фазе компиляции / ссылки пропуститьте, которые не.

5 голосов
/ 02 июня 2011

С помощью gcc, если вы включите опции, он может удалить неиспользуемые функции и мертвый код.

Подробнее об оптимизации gcc можно найти здесь

3 голосов
/ 02 июня 2011

Довольно много времени, да.Его часто называют зачисткой линкера.

2 голосов
/ 02 июня 2011

Когда дело доходит до MS, это компоновщик , который заботится об этом во время фазы соединения, и компилятор может предупредить вас о неиспользуемых статических функциях (область действия файла).Если вы хотите, чтобы компоновщик удалял неиспользуемые функции, вы используете опцию / OPT: REF :

1 голос
/ 24 мая 2012

В MSVC и с глобальными функциями или переменными вы можете использовать __ declspec (selectany) .

Она удалит функцию или переменную, если на нее нет ссылок в коде, если компоновщикопция / OPT: выбран REF (оптимизация).

0 голосов
/ 02 июня 2011

Все зависит от компилятора и его настроек (код, встроенный в «отладочные» конфигурации, как правило, не оптимизирован), а также от самого кода и выравнивания планеты.

Основная вещь: вы не должны беспокоиться об этом. Доверяйте своему компилятору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...