Dead code removal
Reduce file sizes and save in maintenance costs by removing unnecessary dead code. Project Analyzer can reliably detect the dead code in your Visual Basic projects.
What is dead code?
Dead code means unnecessary, inoperative code that can be removed.
Dead code includes functions and sub-programs that are never called, properties that are never read or written, constants and enums that are never referenced. Variables should be both read and written to. User-defined types can also be dead and a project may contain redundant API declarations. Even entire modules and classes can be completely redundant.
The opposite of dead code is live, operational code. There are also several types of semi-dead code, that is, live-looking code and controls that are not actually required at run-time.
Why should I care about dead code?
Dead code is a very usual phenomenon. It can account for 30–40% of a project's size, and increase the EXE or DLL file size by 100s of kilobytes. An average amount of dead code is 15%. The more developers, the tighter the deadlines, the older and larger the system, the more dead code.
Dead code means excessive memory use and slower execution. It also means more code to read and maintain. It leads to higher costs, especially during maintenance. If the code is in there, programmers must spend time understanding it.
Leaving dead code in a completed project means carrying untested code and hidden bugs around. Dead code may inadvertently become operative later, meaning a possible source for errors.
If you are considering the purchase of someone's source, make sure that you are not paying for hundreds of thousands of unnecessary lines. If you just took on a new project, the first thing to do should be to remove any significant dead parts. When you're finishing your newest release, remove the dead bits to ease future maintenance efforts.
Types of dead code
The following is a short list of different types of dead code. This is not a complete list. Project Analyzer supports a wide range of subtypes and special cases.
- A dead procedure is not called and thus not executed. A semi-dead procedure is one that is referenced in the code, but the callers don't execute.
- A dead event does not fire. A truly dead event is not handled nor fired. A semi-dead event just doesn't fire and its handlers never execute.
- A dead variable is not read nor written to. A semi-dead variable is written but not read. Even worse, it may be read but not written, or not written any decent value. A variable may also appear to be in use, yet be faulty if none of the readers or writers execute. In this case the variable is effectively dead or just partially used.
- A dead parameter is passed to the procedure but not used by it. Alternatively, it is used the wrong way, meaning a ByVal parameter is written to in place of reading from it.
- Optional parameter never passed a value happens when a parameter is alive, but it is not being passed as a call argument.
- A dead return value of a function is not stored or used by any of the callers, indicating that the function should probably be a sub. Even if a live return value is used by some of the callers, others may discard it, indicating a potential logic error.
- A dead constant or enum constant is not used anywhere. It may also appear to be in use, yet be useless if none of the user procedures actually execute.
- A dead compiler constant is not used for conditional compilation.
- A dead enum is not used as a datatype and none of its constants are in use either.
- A dead user-defined type is not used anywhere. A dead type field is like a dead variable.
- A dead line label or number is not used as a jump target or for error handling.
- A dead class is not used anywhere. A semi-dead class may be in use as a data type but not instantiated. Alternatively, it's possible that there is no concrete child class for an abstract base class.
- A dead interface is not used anywhere. A semi-dead interface may be in use as a data type but not implemented by any class. Alternatively, the interface may be implemented but nobody actually calls the interface.
- A dead module or file is one whose contents are not used for any purpose.
- A control may be invisible, outside of form borders or disabled during its lifetime. Even if the control's methods and properties are accessed, it may be unnecessary for the operation of the program.
- Code in a library project may be dead within the library itself, but other projects may still call it via the library's exposed interface. This scenario requires that all the user projects are analyzed before the dead code can be safely eliminated. The Enterprise Edition handles this special case.
View Dead code detection in the Online Help for more accurate descriptions on each type of dead code.
Logic problems related to dead code
The following dead code related problems are classified as Logic problems in Project Analyzer. This kind of dead code is related to the execution path of a procedure. In other words, its internal logic.
- Unreachable code cannot run because execution doesn't flow to it. These lines are dead code. This can happen due to an impossible condition, a partially executed loop, a forever loop or a misplaced jump.
- Assigned value not used happens when a variable is written a new value, but the value is not read before being rewritten or going out of scope. The variable is alive, but its value is dead.
- Parameter value not used happens when a ByVal parameter is overwritten before its value is read. The formal parameter is alive, but any passed value is dead, quite the same way as with "Assigned value not used".
- Passed value not used happens at a procedure call statement. One of the call arguments is passed in vain, because its value is not accessed by the called procedure. Again, the passed value is dead, even when the formal parameter appears to be alive.
- Variable read before written happens when execution flows to a read statement before no write can have executed, and also when a write is or is not executed based on the path taken at run-time. The variable is semi-dead in the sense that it doesn't necessarily contain a proper value.
How do I detect and remove dead code?
Project Analyzer (all editions) detects dead code by source code analysis. It shows how much dead and semi-dead code there is and where. Utilizing advanced analysis techniques and an extensive rule base tuned for Visual Basic and VB.NET, Project Analyzer can reliably detect dead code from live code. The analysis works reliably also with the most complex code that utilizes object-oriented techniques and late binding.
Project Analyzer Enterprise Edition makes dead code removal automatic. Its problem auto-fix feature deletes or comments out all dead code. The Enterprise Edition is also good for detecting dead code among project groups and solutions where projects call each other.
VBA Plug enables Project Analyzer to read Office VBA code and detect dead code in it. VBA Plug is optional for Project Analyzer. Read about limitations with dead VBA detection and recommended practices for dead VBA detection.
Super Project Analyzer is an optional tool to Project Analyzer. A super project is a collection of projects that share some source code files. In this setup, a piece of code may be in use in some projects, and dead in the rest. Super Project Analyzer finds code that is never called by any of the projects. Super Project Analyzer is included in the Pro and Enterprise Editions.
Beyond dead code removal: Duplicate code
Besides dead code, projects often contain duplicate code as well. Duplicate code appears because of copy & paste coding. You can decrease your programs further by eliminating the duplicated items. The following features are available in Project Analyzer:
- String literal analysis searches for duplicate strings ("..."). You can save space by reusing string constants. Using the constants also helps you to centralize your string definitions. This feature is available in all Project Analyzer editions.
- Duplicate code analysis finds repeated code blocks, including identical procedures and shorter code snippets. You can often turn duplicate blocks to reusable procedures. If an entire procedure is duplicated, you can usually keep one of them and remove the others. This feature is available in Project Analyzer Enterprise Edition.
- Constant analysis locates duplicate constant definitions, in addition to differing values for the same constant name and other constant flaws. This feature is available in all Project Analyzer editions.
It really solved a big problem we had. We have had a team of 3 people working on the same program for the past 3 years, it is very large. We were able to immediately shave 300k off the size of our executable!
Lance Keene, Sarbrook Company
I purged about 20 dead source files and over 50 dead routines, and also found a number of bugs thanks to your option explicit checking. In our 150,000 line application, it only takes about a minute and a half to perform the initial analysis.
The first project I analyzed, I cut the executable from 2,076 KB to 1776 KB.
I have had another opportunity to test its capabilities. I cut the executable down from 1358 KB to 975 KB.
I removed 7 files and 361KB of source code and the executable size was reduced from 908KB to 652KB. Needless to say, obtaining these results would have been impractical without a dead code detector.
Spontaneous, authentic comments by real users.
Dead code detection and removal
Article about dead code. Why it happens, when to be concerned, how to detect it.
Tool that finds and removes dead code.