什么是最好的命令行工具来清理代码?

34

当我写C代码时,我只使用编辑器和gcc。我想知道是否有人能够建议一个好的简单工具,用来查找未使用的变量、函数声明和可能进行一些优化。

有人知道一个好的工具吗?


如果您需要优化,可以使用gcc的-O开关。 - hyperboreean
2
将投票关闭工具推荐。 - Ciro Santilli OurBigBook.com
6个回答

28

正如 Dan Fego 所指出的那样,GCC 能够捕获未使用的变量和未使用的静态函数。通常情况下,它无法找到未使用的外部函数,因为它通常一次只处理一个源文件。

GCC(v4.3.2)有数百甚至数千个选项。其中一个可能有用的选项是“--combine”以组合源文件(只要您不习惯在不同的源文件中放置相同的函数或变量名称)。(2023-03-10:对 --combine 的支持已于 2012 年被移除——GCC 已经很长时间没有这个选项了。)

选项“--help”会告诉您更多信息;选项“--help=optimizers”和“--help=warnings”分别提供了几百行输出。警告包括:

-Wunused                    This switch lacks documentation
-Wunused-function           Warn when a function is unused
-Wunused-label              This switch lacks documentation
-Wunused-macros             Warn about macros defined in the main file that
                            are not used
-Wunused-parameter          Warn when a function parameter is unused
-Wunused-value              Warn when an expression value is unused
-Wunused-variable           Warn when a variable is unused

补充:这是一个名为glint的脚本,我用它来清理我的代码。它相当古老,因此第一行没有使用'#!/bin/sh'标记,并且使用'$*'而不是'"$@"',这两个问题都应该得到解决,但都不需要紧急处理。请注意,即使GCC 4.x不再支持'-fwriteable-strings'选项,它仍然支持'-Wwrite-strings'选项,并且具有价值。

这个脚本演示了只需很少的工作,就可以从现有工具中获得很多好处。你可以配置它使用的几乎每个选项,尽管主要是通过环境而不是命令行进行配置。当然,你可以在命令行中添加额外的警告选项;但你无法删除预定选项,除非通过环境进行设置。但这没问题;这些选项是基于良好的原因而默认选择的。现在,我可能会设置 'GLINT_ANSI=-std=c99' 或者修复脚本;由于我编码时遵循 glint 强制执行的标准,所以最近没有经常使用它。 (注意,'-o /dev/null' 表示你一次只能处理一个文件;这是一个修补的捷径!)

:   "@(#)$Id: glint.sh,v 1.5 2002/08/09 21:40:52 jleffler Exp jleffler $"
#
#   Use GCC as excruciatingly pedantic lint
#   Not a complete replacement for lint -- it doesn't do inter-file checking.
#   Now configurable via the environment.
#   Use GLINT_EXTRA_FLAGS to set extra flags via the environment.
#   NB: much Solaris code won't work with -undef enabled.

: ${GLINT_GCC:='gcc'}

: ${GLINT_ANSI='-ansi'}
: ${GLINT_FNO_COMMON='-fno-common'}
: ${GLINT_FSHORT_ENUMS='-fshort-enums'}
: ${GLINT_PEDANTIC='-pedantic'}
: ${GLINT_WAGGREGATE_RETURN='-Waggregate-return'}
: ${GLINT_WALL='-Wall'}
: ${GLINT_WCAST_ALIGN='-Wcast-align'}
: ${GLINT_WCAST_QUAL='-Wcast-qual'}
: ${GLINT_WCONVERSION='-Wconversion'}
: ${GLINT_WMISSING_DECLARATIONS='-Wmissing-declarations'}
: ${GLINT_WREDUNDANT_DECLS='-Wredundant-decls'}
: ${GLINT_WMISSING_PROTOTYPES='-Wmissing-prototypes'}
: ${GLINT_WNESTED_EXTERNS='-Wnested-externs'}
: ${GLINT_WPOINTER_ARITH='-Wpointer-arith'}
: ${GLINT_WSHADOW='-Wshadow'}
: ${GLINT_WSTRICT_PROTOTYPES='-Wstrict-prototypes'}
: # ${GLINT_WTRADITIONAL='-Wtraditional'}
: ${GLINT_WWRITE_STRINGS='-Wwrite-strings'}

exec ${GLINT_GCC} \
    ${GLINT_ANSI} \
    ${GLINT_FNO_COMMON} \
    ${GLINT_FSHORT_ENUMS} \
    ${GLINT_PEDANTIC} \
    ${GLINT_WAGGREGATE_RETURN} \
    ${GLINT_WALL} \
    ${GLINT_WCAST_ALIGN} \
    ${GLINT_WCAST_QUAL} \
    ${GLINT_WCONVERSION} \
    ${GLINT_WMISSING_DECLARATIONS} \
    ${GLINT_WREDUNDANT_DECLS} \
    ${GLINT_WMISSING_PROTOTYPES} \
    ${GLINT_WNESTED_EXTERNS} \
    ${GLINT_WPOINTER_ARITH} \
    ${GLINT_WSHADOW} \
    ${GLINT_WSTRICT_PROTOTYPES} \
    ${GLINT_WTRADITIONAL} \
    ${GLINT_WWRITE_STRINGS} \
    ${GLINT_EXTRA_FLAGS} \
    -o /dev/null -O4 -g -c $*

15

Lint是检查C程序风格的经典工具。现在有一个更现代化的版本叫做Splint。 这篇维基百科文章列出了一些静态代码分析工具,有些是免费的,有些是商业软件。


11

虽然我确定这不是一个全面的静态代码分析工具列表,但以下是我过去使用过的一些不同工具的印象。(我主要使用C语言。)

  1. Splint:我经常使用Splint,因为它适用于许多GNU/Linux发行版。它相对容易使用;但是,在最严格的设置下操作时,它往往会让人感到不知所措。此外,有时必须使用注释,这可能会使易于阅读的代码变得混乱和难以理解。尽管如此,我仍建议使用它。

  2. Uno:Uno绝对是一个有前途的工具,但它不像Splint那样严格(出于设计考虑)。相反,它专注于其警告的清晰度和实用性。对我来说,Uno只有作为Splint的补充才有用(以便清楚地指出隐藏在Splint发出的相对较多警告中的警告)。

  3. PC-lint:我发现PC-lint对于专有程序来说过于笨重。我曾经在为MS-DOS开发时使用过它,它使用的加密名称使其非常难以使用。据我所听,有许多更好的产品可用于MS-DOS。

  4. Pscan:(无效链接)Pscan非常适合查找格式字符串漏洞!与Uno一样,我建议将其作为Splint的补充使用。

如果你不使用C语言,你也许想要查看以下内容:Wikipedia - 静态代码分析工具列表, 检查/审查工具,源代码/二进制代码静态分析器, 以及源代码安全性分析器


PC-Lint的注释对我来说很奇怪 - 这是我见过的最好的文档之一。由于选项和错误数量众多,它确实不易使用 - 但在我看来,这就是问题的本质。除非你想要别人定义的检查/忽略方式。 - Steve Fallows
@Steve:我一定错过了文档。我已经纠正了这篇文章,以免误导任何人。谢谢。 - anon

6

如果你使用-Wall参数运行gcc编译器,它会捕捉到你提到的一些问题,比如未使用的变量(也许是未使用的函数)。就优化而言,我不担心,因为通常情况下编译器足够聪明,能够进行有意义的优化。只需避免使用可怕的算法就好了。;-)


3
除了使用-Wall之外,还应该使用-Wextra。 - splicer

3

splint(http://www.splint.org/)非常出色;我已经在大型代码中使用它来查找这种问题,

(更新:每个人都想成为艺术总监。)


1
提供Splint的URL会很好。'分号后'句子需要澄清。我不清楚'itm one megaline codes'是另一个产品还是'it on megaline codes'的打字错误,意思是大型代码库。 - Jonathan Leffler

0

你考虑使用分析器来查找哪些代码运行最频繁,集中精力优化这些部分。

也许gprof可以帮助你解决问题?

/Johan

修改:或者,根据你谈到的清理操作,反转我的上述答案并删除从未执行过的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接