2013-09-19 1 views
4

У меня есть полный проект на C, который можно построить с помощью gcc или Visual Studio. Во внешних библиотеках нет вызовов.Функции подсчета в исходном коде С

Я хотел бы знать, сколько функций есть в этом проекте.

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

Есть ли инструменты, которые могут выполнять статические или динамический анализ?

+1

Я уверен, что ваш код вызова функции из стандартной библиотеки C (например, 'printf' ...), так что вам есть по крайней мере, одна внешняя библиотека, стандартная C ... –

+0

Ну, на самом деле вы не можете быть уверены в этом. Это сложный вычислительный механизм, и системные вызовы преднамеренно опущены, когда это возможно. Даже если есть некоторые, это похоже на 5 против 2000, так что это не имеет большого значения. – mszabc

+0

Но 'printf' не является системным вызовом. Моя точка зрения состоит в том, что переносимый C-код приложения (а не свободностоящий), который не использует стандартную библиотеку, бесполезен (если он не использует другие библиотеки), потому что он не может делать никаких ввода или вывода ... –

ответ

4

С gcc:

$ nm elf_file | grep "T " | grep -v " _" | wc -l 

Обратите внимание, что gcc может встраивать некоторые функции даже при оптимизации с ограниченными физическими возможностями, так что вы должны компилировать с:

-O0 -fno-builtin -fno-inline-functions-called-once

(-finline-functions-called-once включена по умолчанию, даже в -O0)

+4

Это * не * GCC специфический, он специфичен для файлов ELF .... (и многих Linux или других Unix-систем ...) –

+0

@BasileStarynkevitch хорошо, что OP упоминает gcc и Visual Studio в своем вопросе, и это не относится к Visual Studio. .. – ouah

+0

@ouah, отличная идея, вот что мне нужно. – mszabc

3

Определения n функций может быть не так просто, как вы считаете. В частности, функции в исходном коде C не соответствуют функциям в сгенерированном коде сборки, особенно из-за встроенных функций.

Количество и размер функций зависят от уровня оптимизации и компилятора.

И многие заголовки (например, <stdio.h>) могут содержать встроенные функции. Если они не вызываются, компилятор, вероятно, будет оптимизирован, не испуская свой код (и то же самое может быть правдой с некоторыми статическими функциями). Довольно часто функции, объявленные static inline, не отображаются в оптимизированном коде.

Кроме того, некоторые макросы могли бы быть расширены в некоторые определения функций ....

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

Обратите внимание, что GCC может генерировать или удалить некоторые функции во время оптимизации (function cloning, function inlining ....)

Очередной выпуск РАСПЛАВА обеспечит такие измерения

3

Frama-C имеет metrics плагин что, помимо прочего, вычисляет количество функций в вашей программе. Просто используйте

frama-c -metrics file1.c file2.c ... filen.c 

, чтобы получить как можно вывести что-то вроде:

  Global metrics 
     ============== 
     Sloc = 2080 
     Decision point = 117 
     Global variables = 51 
     If = 117 
     Loop = 22 
     Goto = 75 
     Assignment = 613 
     Exit point = 242 
     Function = 841 
     Function call = 871 
     Pointer dereferencing = 447 
+0

+1 (я работаю в той же лаборатории, что и Virgile). Возможно, * Frama-C * не будет, например, встроенными функциями, или удалить мертвые функции (например, те, которые предоставляются системными заголовками, которые не могут быть полезны в проанализированный исходный код). Напротив, оптимизирующий компилятор (например, GCC, даже инструмент с MELT) сделает это. Это действительно зависит от того, что OP хочет измерить. –

+0

Действительно, Frama-C будет считать все функции, которые определены или объявлены в исходном коде (после ссылки, так что если у вас есть 'extern void f (void)' в одном файле и 'void f() {}' в другой, он будет засчитан один раз. Если вы хотите посчитать другие вещи, вам придется использовать плагин преобразования кода (или написать свой собственный, если ни один из существующих не сделает то, что вы хотите), и использовать «метрики» на результат , – Virgile

0

Вы также можете использовать Ctags и синтаксического разбора файла тегов.Быстрый способ будет сделать что-то вроде:

ctags -R -f - . | grep -w f | wc -l 

в корневой директории вашего проекта, но это может быть не всегда верно, например, если у вас есть глобальная переменная вроде этого где-то в дереве:

int f; 
0

У меня есть идея подсчитать функции .c файл .. wecan тоже зачислить этот .java файл. это C# класс файл, и вы можете передать файл в классе

class CountFunctions 
{ 

    private FileInfo File; 
    private int functions = 0; 

    public int getNumberOfFunctions 
    { 
     get { return functions; } 
    } 

    public countfunctions(FileInfo fs) { 
     File = fs; 
     getLineOfCode(); 
    } 

    private void getLineOfCode() 
    { 
     string line; 
     try 
     { 
      StreamReader reader = File1.OpenText(); 
      while (true) 
      { 
       line = reader.ReadLine(); 

       if (IsFunction(line)) 
       { 
        Functions++; 
       } 

       if (line == null) 
        break; 
      } 
     } 
     catch (Exception r) 
     { 
      Console.WriteLine(r.Message); 
     } 

    } 

    private bool IsFunction(string line) 
    { 
     if (line.Contains("void") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double")) 
     { 
      if (!line.Contains(";")) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
}