Подтвердить что ты не робот

Есть ли способ получить предупреждение о неиспользуемых функциях?

Я хотел бы найти неиспользуемые функции в базе кода - в том числе и в единицах компиляции. Я использую gcc как мой компилятор.

Вот пример:

foo.c (предположим, соответствующий foo.h):

void foo() {
   ....
}

void bar() {
   ....
}

main.c:

#include <stdio.h>
#include "foo.h"  

int main(void)  {
    bar();
    return 0;
}

В этом примере я хотел бы получить предупреждение о том, что foo() не используется.

Существует опция -Wunused-function gcc:

-Wunused-function

Предупреждать о том, что статическая функция объявлена, но не определена или неиспользуемая статическая функция не используется. Это предупреждение            включено -Wall.

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

Я также буду принимать предложения инструментов/скриптов/других компиляторов, которые могут сделать это для меня, хотя я бы предпочел придерживаться gcc, если это возможно.

4b9b3361

Ответ 1

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

Он называется callcatcher. Он может

собирать функции/методы, определенные и вычитаемые вызываемые/ссылочные

Он работает непосредственно на выходе ассемблера и поэтому работает только для архитектуры x86 и x86_64. Он может производить вывод, например this. Вы можете интегрировать его с традиционным компиляцией и ссылкой на gcc.

Caolan соглашается, что он должен стать gcc-плагином.

Ответ 2

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

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

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

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

Не стесняйтесь спрашивать меня по электронной почте.

Ответ 3

Я знаю, что вы просили предупреждения и предпочитаете не использовать опцию gcc, но это очень просто.

Вы можете использовать оптимизацию компоновщика (-gc-sections), чтобы удалить мертвый код из вашего приложения.

На странице gcc man:

- ГЦ-секции --no-ГЦ-секции Включить сбор мусора из неиспользуемых разделов ввода. Он игнорируется в отношении целей, которые не поддерживают этот параметр. Поведение по умолчанию (не выполнять эту сборку мусора) можно восстановить, указав в командной строке --no-gc-разделы.

- gc-sections решает, какие секции ввода используются при анализе символов и перемещений. Раздел, содержащий символ ввода и все разделы, содержащие символы undefined в командной строке, будет сохранен, как и разделы, содержащие символы, на которые ссылаются динамические объекты. Обратите внимание, что при создании разделяемых библиотек компоновщик должен предположить, что на любой видимый символ ссылаются. Как только этот начальный набор разделов определен, компоновщик рекурсивно отмечает, как используется любой раздел, на который ссылаются их перемещения. См. Раздел --entry и - undefined.

Эта опция может быть установлена ​​при выполнении частичной ссылки (включена с параметром -r). В этом случае корень сохраняемых символов должен быть явно указан либо с помощью параметра -entry или - undefined, либо командой "ENTRY" в компоновщике script.

Ответ 4

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

Ответ 5

gprof - самое простое решение, которое я предполагаю. Я скомпилировал примерную программу, которую вы установили с опцией -pg, чтобы мы получили gmon.out при запуске a.out (который gprof может использовать позже), а затем я наконец побежал gprof -z a.out gmon.out | tee output.txt. Я могу найти вашу функцию foo в неиспользуемом списке! т.е. называется 0 раз. -z - это опция, которую вы должны использовать вместе с gprof для отслеживания неиспользуемых процедур.

Благодаря этот поток для соответствующего указателя!

PS: gprof забросил множество неиспользуемых функций библиотеки вместе с вашей неиспользуемой функцией foo. Я серьезно не знаю, как отфильтровать это:)