tags:

views:

1689

answers:

8

When I'm writing C - code I solely use an editor and gcc. I was wondering if anyone could suggest a good and simple tool that will find unused variables, function declarations and possibly make some optimisations.

Does anybody know a good tool?

+4  A: 

If you run gcc with -Wall, it'll catch some of the things you mention, such as unused variables (and perhaps unused functions). In terms of optimizations, I don't, though in general the compiler is smart enough to make the kinds of optimizations that matter, so I wouldn't worry too much. Just don't use horrible algorithms. ;-)

Dan Fego
+9  A: 

Lint is the classic tool for checking style on C programs. There's more modern incarnation of it called Splint. This Wikipedia entry has a list of static code analysis tools, some free, some commercial.

ConcernedOfTunbridgeWells
A: 

If you need optimization you could use gcc's -O switch.

hyperboreean
+15  A: 

As Dan Fego pointed out, GCC can catch unused variables and unused static functions. It won't normally find unused extern functions as it normally works one source file at a time.

GCC (v4.3.2) has hundreds if not thousands of options. One that might help is '--combine' to combine source files (as long as you're not in the habit of putting the same function or variable names inside different source files).

The option '--help' tells you more; the options '--help=optimizers' and '--help=warnings' each give you a couple hundred lines of output. The warnings include:

-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


Added: this is a script called glint that I use to sanitize my code. It is quite old so it doesn't use the '#!/bin/sh' notation for the first line and it says '$*' instead of '"$@"', both of which should be fixed, but neither needs to be fixed urgently. Note that even though GCC 4.x no longer supports the '-fwriteable-strings' option, it still supports the '-Wwrite-strings' option and that has value.

This script demonstrates that you can get a lot of mileage out of existing tools with just a small amount of work. You can configure just about every option it uses - albeit mainly via the environment rather than the command line. Of course, you can add extra warning options to the command line; what you can't do is remove predetermined options except via the environment. But that's OK; they're chosen by default for good reasons. These days, I'd probably set 'GLINT_ANSI=-std=c99' or fix the script; I've not been using it much of late since I code fairly closely to the standard that glint enforces. (Note that the '-o /dev/null' means that you can only do one file at a time; hack to fix!)

:   "@(#)$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 $*
Jonathan Leffler
A: 

splint (http://www.splint.org/) is quite excellent; I've used it one megaline codes to look for this sort of thing,

(Updated: everybody wants to be an art director.)

Charlie Martin
Giving a URL for splint would be nice. The 'post-semicolon' sentence needs clarification. I'm not clear whether 'itm one megaline codes' is another product, or a typo for 'it on megaline codes', meaning large code bases.
Jonathan Leffler
+2  A: 

Although I am sure that this is not a comprehensive list of static code analysis tools, here are my impressions of some different ones that I've worked with in the past. (I work mostly with C.)

  1. Splint: I often use Splint because it is available for many GNU/Linux distributions. It is relatively easy to work with; however, it tends to be overwhelming when operating under the strictest setting. Moreover, the sometimes-necessary use of annotations can clutter and obfuscate easily-readable code. Regardless, I suggest using it.

  2. Uno: Uno is definitely a promising, but it is not as rigorous as Splint (by design). Instead, it focuses on the clarity and usefulness of its warnings. For me, Uno is only useful as a supplement to Splint (to clearly point out warnings hidden among the comparatively many that Splint issues).

  3. PC-lint: I find that PC-lint is unwieldy for a proprietary program. I once used it when developing for MS-DOS and cryptic names it uses for its errors made it very difficult to use. From what I hear, there are many better products to use on MS-DOS.

  4. Pscan: (Dead hyperlink) Pscan is great for finding format string vulnerabilities! As with Uno, I suggest using it as a supplement to Splint.

If you do not work with C, you may also want to check out: Wikipedia - List of tools for static code analysis, Inspection/Review Tools, Source/Binary Code Static Analyzers, and Source Code Security Analyzers.

Anthony Cuozzo
PC-Lint comments are strange to me - some of the best documentation I've ever seen. It *is* unwieldy due to large number of options and errors - but IMO that's the nature of the beast. Unless you want someone else's definition of what to check/ignore.
Steve Fallows
@Steve: I must've missed the documentation. I've corrected the post so as to not mislead anyone. Thank you.
Anthony Cuozzo
+2  A: 

Well, for some code the only option is:

rm -rf .
dsimcha
A: 

How about to use a profiler and find what code is running the most, and focus in on those parts.

Maybe gprof can help out?

/Johan

Edit: Or since you talked about cleanup, invert my answer above and remove the code that never executes.

Johan