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?
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.
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.
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:
Make with ctags (or similar programm) a list of all your symbols in your source
Enable in your compiler the dead code elimination (I would assume it defaults to on)
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)
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).
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.
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.
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.
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.
Related
During my regular builds, I have /W4 turned on, with a few additional warnings as well, and some that are simply disabled due to too many false positives with Visual Studio. This mostly works okay, but I'd still like, from time to time, to check on all warnings which /Wall would give.
My preference would be to do this during Code Analysis, which I run about once a week anyway. I already have a custom ruleset file for CA, but I can't figure out how to enable additional non-CA warnings in it. I've also tried looking in the .vcxproj files to see if there's anything in there which is specific to CA, but I couldn't find anything.
Additional info: I use CMake to create the projects, so it would be preferred if it's something I can do in there, but I can probably modify my CMake myself to work with potential solutions. Also, all projects are C++ (not CLI) except one which is C#.
I have a large C++ project of hundreds of files with a CMake build system. How can I use GCC's -ftime-report option but get a single summary for the full build?
I am looking to improve build times and this would be helpful to know where to focus the effort.
You would need to implement that manually by parsing the output somehow.
A good way to get a higher level overview is to use Ninja and parse the .ninja_log file:
https://github.com/ninja-build/ninja/issues/1080#issuecomment-255436851
Also see https://github.com/nico/ninjatracing. Chromium uses tools like that to keep track of build times.
Update:
-ftime-report is simply not suitable for this task as it's meant for compiler devs. Use clang and https://github.com/aras-p/ClangBuildAnalyzer for this.
gcc is far from supporting -ftime-trace: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92396
I have recently upgraded from Visual Studio 2012 to 2017 and I'm experimenting with the Code Analysis features (which seem to be far more capable than they were in 2012).
The problem I have is that I'll get many results for code dependencies, whereas I am really only interested in my own local project files. This is particularly true when I have Enable C++ Core Check (Released) enabled.
For example, as shown above, I receive multitudes of analysis results for the boost libraries. There are tons of results for xerces-c, and other libraries which I'm using as well.
Is there a way to restrict the analysis to only those files which I have written myself (local to the project)?
There isn't a flag or setting that I'm aware of to directly accomplish this, but you can get something close by using #pragma warning to change the warning level (or disable specific warnings) before you include those library headers, then restore the warning level before including your own.
It isn't perfect, and could result in suppressing warnings you'd want to see, but if you only disable them during Code Analysis that wouldn't be an issue.
I have a lot of unmanaged C++ code written quite some time ago. Now, I'm wanting to go back and add automated tests to that code using MS Test (built into Visual Studio). However, in order to do that, I either have to build the C++ as a .lib file and write a wrapper layer around it (in order to call it from C# tests) or I need to be able to compile the code as managed. The first option I've got worked out, but ideally I'd prefer to use the second option so that don't need the wrapper layer. Note, even though I mentioned writing the Test code in C#, that's not necessarily a requirement.
So, I changed the Project's properties such that the "Common Language Runtime Support" property changed from "No Common Language Support" to "Common Language Runtime Support (/clr)". Now when I try to compile, I get an error that reads
"error D8016: '/ZI' and '/clr' command-line options are incompatible"
Does anyone have idea what this really means and how I can work out the aforementioned problem? Have you done this before? I've been searching and reading about it online now for quite some time and I've really come away empty handed with no real answers.
Any tips or advice would be much appreciated.
Thanks.
The /ZI option is for edit-and-continue with native code.
Try the very similar /Zi option instead. Debug database without the edit-and-continue feature.
I'm doing some refactoring in a project using Qt with Visual Studio 2008, and I'd like to know if there's a simple way to find the functions and methods that are never called?
You can try a static code analysis tool, like http://en.wikipedia.org/wiki/Cppcheck
A -Wall in your compilation options should do it. (Or -Wunused-function). Check the compilator options in VS.
I've always preferred "grep", but that may be a bit "old-school".
Visual Studio will build a call-graph for you that is helpful but not 100% reliable.
Another alternative is comment out the function and see if the project will still link.
Is there a chance to build this Qt Project using gcc? If so, you could use gcov. It tells you all methods which were called during execution. Then you could use ctags to create a list of all methods available. From these two sets you could find those, not being called.
Of cause the application should run long enough under gcov for delivering more or less complete list of used functions.
(I guess there is an easier way using linker or a compiler switch. :-))