Dead code identification (C++)

2019-01-10 18:51发布

问题:

I have a large legacy C++ project compiled under Visual Studio 2008. I know there is a reasonably amount of 'dead' code that is not accessed anywhere -- methods that are not called, whole classes that are not used.

I'm looking for a tool that will identify this by static analysis.

This question: Dead code detection in legacy C/C++ project suggests using code coverage tools. This isn't an option as the test coverage just isn't high enough.

It also mentions a -Wunreachable-code. option to gcc. I'd like something similar for Visual Studio. We already use the linker's /OPT:REF option to remove redundant code, but this doesn't report the dead code at a useful level (when used with /VERBOSE there are over 100,000 lines, including a lot from libraries).

Are there any better options that work well with a Visual Studio project?

回答1:

You'll want something along the lines of QA-C++ (http://www.programmingresearch.com/QACPP_MAIN.html), also see http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis for similar products.

You're looking for a static code analysis tool that detects unreachable code; many coding guidelines (such as MISRA-C++, if I'm not mistaken) require that no unreachable code exists. An analysis tool geared specifically to enforce such a guideline would be your best bet.

And you'll like be able to find other uses for the tool as well.



回答2:

I know that Gimpel's Lint products (PC-Lint and Flexelint) will identify unreachable code and unused / unreferenced modules.

They both fall in the category of static analysis tools.

I have no affiliation w/ Gimpel, just a satisfied long-term customer.



回答3:

I dont know Visual C, and had also recommended the -Wunreachable-code specific coverage tools. As solution for your situation I would try the following:

  1. Make with ctags (or similar programm) a list of all your symbols in your source
  2. Enable in your compiler the dead code elimination (I would assume it defaults to on)
  3. Enable your whole-program/link time optimizations (so he knows that not used functions in your moduls are not required by other externals and get discarded)
  4. Take the symbols from your binary and compare them with the symbols from 1.

Another approach could be some call graph generating tool (e.g. doxygen).



回答4:

I suggest you use a couple approaches: 1. GCC has some useful compilation flags:

-Wunused-function
-Wunused-label
-Wunused-value
-Wunused-variable
-Wunused-parameter
-Wunused-but-set-parameter

2. Cppcheck has some useful features like:

 --enable=unusedFunction

3. Use static analyzer as was suggest before.



回答5:

One approach that works for me - with Delphi - is to enable debugging, and run your program under the debugger.

When a Delphi program is run under the debugger, the IDE shows in the margin which lines of code can be set as breakpoints. Code which is truly dead - i.e., has been stripped out by the linker/compiler is obvious as breakpoints can't be set there.

Some additional notes, as commenters seem to misunderstand this:

a: You don't need to try setting a breakpoint on each line. Just open up the source file in the IDE, and quickly scroll through it. Dead code is easily spotted.

b: This is NOT a 'code coverage' check. You don't need to run the application to see if it reaches the lines.

c: I'm not familiar enough VS2008 so can't say if this suggestion will work.



回答6:

Either
1) MSVC's under-used in built static analysis tool.
2) The MSVC marketplace has lots of tools including support for most free tools, including CppCheck

You will need the latest version of Visual Studio for market place applications, but the free "Community Edition" has very lenient licencing.



回答7:

Write a script that randomly deletes a function (from the source code) and recompiles everything from scratch. If it still compiles - that function was dead code.