We often hear the term “dead code,” but what does it mean and more importantly why should we care? Before we answer that, let’s examine various kinds of dead code and then we can look at their impact.
There are three main types of dead code: unexecutable statements, unexecutable paragraphs or procedures and unexecutable programs.
Unexecutable statements: You probably have many statements scattered throughout your programs that just cannot be executed. It could be that there is a GO TO statement right above it. Those can be somewhat easy to spot and understand, but other times they can be more difficult to detect. An example would be when there is a Perform or CALL statement preceding it. The logic terminates there and cannot return. This often happens with error handling routines. They typically end the program so it can’t come back to the following statements.
Unexecutable paragraphs or procedures: In this case there is no place where they are called or performed and no path to “fall through” to them. They appear to be important parts of the logic, but cannot be executed.
Programs that just aren’t used: These programs are in your inventory and were written for a purpose, but there is no transaction, job or program that executes them.
There is another type of code humorously referred to as “sleeping” code. It could logically be run, but there are no data or conditions that would follow that path anymore. Sometimes sleeping code can be spotted by someone who knows your business and the application. They will know why the code was written, to handle a special condition, for example, but they will also know that condition no longer applies. Without that institutional knowledge, these are very difficult to locate without running through all your normal scenarios with a code coverage tool. Code that isn’t executed should be reviewed for relevancy.
How does code die? There are many ways—both accidental and deliberate. In an “accidental death,” the developer could have laid out their logic, placed a GO TO but didn’t consider the code following it. It’s the type of thing that may not be picked up in normal testing or a code review. This same thing could happen during changes, where something as simple as a misplaced period or statement changes the flow in a way that is not obvious.
Sometimes the developer will deliberately eliminate the code because the logic is no longer needed, or maybe it could have caused a problem or was so confusing that the developer wrote replacement logic. But instead of removing the code or commenting it out, they leave it in. I’ve heard some say they leave it in because they don’t know if it isn’t used somehow, so they don’t want to take a chance and remove it. Other times it’s just the change of business: That line of business is no longer valid, those jobs are no longer run, etc.
So, what impact can sleeping code have on a program? One could consider the size of the code, but often, it doesn’t take up much of the program source, and optimizing compilers attempt to remove the code before being put in the load module. So, size shouldn’t be a factor; it is more for maintainability. The problems come in two areas. First is when someone is assigned to make a change to a program and they don’t understand the nature of the code. When reviewing the logic, it’s bad enough that they have to take time to review it. But worse, they may assume the statements are a part of the logic and plan to use them. At the very least, these extra statements provide bloat and confusion.
The more serious problem with dead code is probably the one that happens more often. This code is lying dormant and isn’t hurting anything, but when someone goes in to make a change, they could inadvertently bring this code back to life. Suddenly things don’t work the way they did before and no one can understand why. The statements were there before, so the expectation is that they were executing before. This makes debugging very difficult. What if the code was a security check? This is something that may not be obvious in normal running, but has serious consequences. (I recall once presenting the analysis of an application where I found a large section of dead code. Two people leapt out of their seats, stared at the screen and started talking about the consequences. This was code which was supposed to execute every day, but wasn’t.)
It’s probably not worth the effort to just locate and eliminate dead code as a project, per se. But whenever changes are made, dead code should be located in the programs and evaluated; if it’s not needed, it should be commented out with an explanation and the date. Then the next time the code is updated it can be removed with a comment, assuming enough time has passed. You hadn’t needed it after all, and with source backups, you could get it back if necessary. Using this approach, over time, you will improve the maintainability of your portfolio and head off costly problems.