当我编写C代码时,我只使用编辑器和gcc.我想知道是否有人可以建议一个好的和简单的工具,将找到未使用的变量,函数声明,并可能进行一些优化.
有人知道一个好工具吗?
正如Dan Fego指出的那样,GCC可以捕获未使用的变量和未使用的静态函数.它通常不会找到未使用的外部函数,因为它通常一次只能处理一个源文件.
GCC(v4.3.2)有数百个(如果不是数千个)选项.可能有帮助的是' --combine
'组合源文件(只要你不习惯将相同的函数或变量名放在不同的源文件中).
选项' --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_UNDEF='-undef'} : ${GLINT_W='-W'} : ${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_UNDEF} \ ${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_W} \ ${GLINT_EXTRA_FLAGS} \ -o /dev/null -O4 -g -c $*
Lint是检查C程序样式的经典工具.它有更现代的化身,称为Splint. 这个维基百科条目有一个静态代码分析工具列表,一些是免费的,一些是商业的.
虽然我确信这不是一个完整的静态代码分析工具列表,但这里是我过去曾与之合作的一些不同的印象.(我主要与C一起工作.)
Splint:我经常使用Splint,因为它可用于许多GNU/Linux发行版.工作相对容易; 然而,在最严格的环境下操作时,它往往是压倒性的.此外,有时必要的注释使用会使易于阅读的代码变得混乱和混淆.无论如何,我建议使用它.
Uno:Uno绝对是一个很有前景的产品,但它并不像Splint那样严格(按设计).相反,它侧重于其警告的清晰度和有用性.对我来说,Uno仅作为Splint的补充(用于清楚地指出隐藏在Splint发布的相对多的警告中).
PC-lint:我发现PC-lint对于专有程序来说是不实用的.我曾经在开发MS-DOS时使用它,并且它使用的神秘名称因为它的错误而使用起来非常困难.据我所知,在MS-DOS上有许多更好的产品可供使用.
Pscan :(死超链接)Pscan非常适合查找格式字符串漏洞!和Uno一样,我建议使用它作为Splint的补充.
如果您不使用C,您可能还需要查看:Wikipedia - 静态代码分析,检查/审查工具,源/二进制代码静态分析器和源代码安全分析器的工具列表.
如果你用-Wall运行gcc,它会抓住你提到的一些东西,比如未使用的变量(也许是未使用的函数).在优化方面,我没有,尽管一般来说编译器足够聪明,可以进行重要的优化,所以我不会太担心.只是不要使用可怕的算法.;-)