4

我有完整的 C 项目,可以用 gcc 或 Visual Studio 构建。没有调用外部库。

我想知道该项目中有多少功能。

源代码中没有未使用的函数,并且该项目附带了使用不同参数运行它的测试,因此对于动态方法(例如运行时调用树),我需要在每次测试后累积结果。

有没有可以进行静态动态分析的工具?

4

6 回答 6

5

gcc

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

请注意, gcc即使禁用优化也可以内联某些函数,因此您应该编译:

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

-finline-functions-called-once即使在 中也默认启用-O0

于 2013-09-19T08:32:03.097 回答
4

函数的定义可能不像你想象的那么简单。特别是,C 源代码中的函数与生成的汇编代码中的函数不匹配,这主要是因为内联函数。

函数的数量和大小取决于优化级别和编译器。

许多标头(例如<stdio.h>)可能包含内联函数。如果不调用它们,编译器可能会通过不发出它们的代码来优化(对于某些静态函数也是如此)。很多时候,声明的函数static inline不会出现在优化的代码中。

同样,一些宏可能会扩展为一些函数定义......

如果使用足够新的 GCC 版本(例如 4.7 或更高版本)进行编译,您可能会为此目的制作一个简单的MELT扩展。最大的优点是它可以在 GCC 内部工作,因此会真正计算 GCC 正在做什么……(例如,经过一些优化)。

请注意,GCC 可能会在优化期间生成或删除一些函数(函数克隆函数内联....)

GCC MELT 自 2017 年起已过时

于 2013-09-19T08:32:37.753 回答
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
于 2013-09-19T13:11:31.377 回答
1

您还可以使用 ctags 并解析标记文件。一种快速的方法是执行以下操作:

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

在项目的根目录中,但这可能并不总是正确的,例如,如果您在树的某处有这样的全局变量:

int f;   
于 2013-09-19T14:22:14.470 回答
0

Edison Design Group 是一个对 C 源代码进行静态分析的工具。它是编译器前端,您可以利用它来计算代码的各种指标。

于 2019-01-26T10:07:50.527 回答
-1

我有一个想法来计算函数 .c 文件。我们也可以计算这个 .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;
    }
} 
于 2015-07-21T18:01:11.803 回答