代码之家  ›  专栏  ›  技术社区  ›  Nick Bastin

用于查找未使用的包含标题的工具?[关闭]

  •  76
  • Nick Bastin  · 技术社区  · 16 年前

    PC-Lint

    9 回复  |  直到 12 年前
        1
  •  29
  •   Richard Corden    16 年前

    免责声明: 我的日常工作是为一家开发静态分析工具的公司工作。

    如果大多数(如果不是全部)静态分析工具没有某种形式的标头使用检查,我会感到惊讶。你可以使用 this

    在评估工具时,您可能会考虑以下几点:

    // f1.h
    void foo (char);
    
    // f2.h
    void foo (int);
    
    
    // bar.cc
    #include "f1.h"
    #include "f2.h"
    
    int main ()
    {
      foo (0);  // Calls 'foo(int)' but all functions were in overload set
    }
    

    当你有局部和专业化时,也适用类似的规则。无论是否选择专业化,您都需要确保所有专业化都是可见的:

    // f1.h
    template <typename T>
    void foo (T);
    
    // f2.h
    template <>
    void foo (int);
    
    // bar.cc
    #include "f1.h"
    #include "f2.h"
    
    
    int main ()
    {
      foo (0);  // Calls specialization 'foo<int>(int)'
    }
    

    对于重载示例,暴力方法可能会导致程序仍能编译,但行为不同。

    您可以注意的另一种相关分析类型是检查类型是否可以前向声明。请考虑以下几点:

    // A.h
    class A { };
    
    // foo.h
    #include "A.h"
    void foo (A const &);
    
    // bar.cc
    #include "foo.h"
    
    void bar (A const & a)
    {
      foo (a);
    }
    

    在上面的例子中,不需要“A”的定义,因此可以更改头文件“foo.h”,使其仅对“A”进行正向声明:

    // foo.h
    class A;
    void foo (A const &);
    

        2
  •  22
  •   Andy C    14 年前

    #!/bin/bash
    # prune include files one at a time, recompile, and put them back if it doesn't compile
    # arguments are list of files to check
    removeinclude() {
        file=$1
        header=$2
        perl -i -p -e 's+([ \t]*#include[ \t][ \t]*[\"\<]'$2'[\"\>])+//REMOVEINCLUDE $1+' $1
    }
    replaceinclude() {
       file=$1
       perl -i -p -e 's+//REMOVEINCLUDE ++' $1
    }
    
    for file in $*
    do
        includes=`grep "^[ \t]*#include" $file | awk '{print $2;}' | sed 's/[\"\<\>]//g'`
        echo $includes
        for i in $includes
        do
            touch $file # just to be sure it recompiles
            removeinclude $file $i
            if make -j10 >/dev/null  2>&1;
            then
                grep -v REMOVEINCLUDE $file > tmp && mv tmp $file
                echo removed $i from $file
            else
                replaceinclude $file
                echo $i was needed in $file
            fi
        done
    done
    
        3
  •  5
  •   Ton van den Heuvel    14 年前

    看一看 Dehydra .

    来自网站:

        4
  •  4
  •   Chance    11 年前

    谷歌的 cppclean

        5
  •  3
  •   Mirko Stocker    14 年前
        6
  •  1
  •   Cinder6    16 年前


    对于每个标题,包括
    注释掉include

    if(compile_errors)

    否则

    把它放在夜间cron中,它应该能完成这项工作,使有问题的projcet没有未使用的头文件(很明显,你总是可以手动运行它,但执行起来需要很长时间)。唯一的问题是,不包含标头不会产生错误,但仍然会产生代码。

        7
  •  1
  •   quamrana Ryuzaki L    16 年前

    我手动完成了这项工作,由于编译时间减少,在短期内(哦,这是长期的吗?-这需要很长时间)是值得的:

    1. 每个cpp文件需要解析的头更少。

    这也是一个递归过程——每个保留的头文件都需要检查是否有任何头文件

    实际上,我对C++编译器有点恼火,它们应该能够告诉你什么是不需要的——微软编译器可以告诉你什么时候可以在编译过程中安全地忽略对头文件的更改。

        8
  •  0
  •   Arctica    12 年前

    由于它是用Java编写的,因此显然可以在linux上运行。

    该项目的链接是 https://sourceforge.net/projects/chksem/files/chksem-1.0/

        9
  •  -1
  •   John Hainsworth    12 年前

    如果您首先确保每个头文件都能自行编译,那么删除未使用的包含的大多数方法都会更好。我按如下方式相对快速地完成了这项工作(为拼写错误道歉——我在家打字:

    find . -name '*.h' -exec makeIncluder.sh {} \;
    

    哪里 makeIncluder.sh 包含:

    #!/bin/sh
    echo "#include \"$1\"" > $1.cpp
    

    ./subdir/classname.h ./subdir/classname.h.cpp 包含线条

    #include "./subdir/classname.h"
    

    makefile 在。目录编译所有cpp文件并包含 -I. ,然后重新编译将测试每个包含文件是否可以自行编译。使用goto-error在您最喜欢的IDE中编译,并修复错误。

    find . -name '*.h.cpp' -exec rm {} \;

    推荐文章