There’s a “dead code” code smell mentioned in Refactoring. The refactoring is to delete the code. OK, easy enough to do. Over the years, I’ve identified a few handy ways of identifying the dead code laying around in your code base. That way you can ferret it all out at once and get rid of it. This specific example is for C++, but you can apply the techniques to any language.
This post talks about the Visual Studio way of doing it. If you develop under emacs, I know that emacs has a way to invoke grep combined with find to search over a directory hierarchy. I’m not familiar with other IDEs like Xcode or Eclipse, so I can’t say if they have a similar search feature, but it seems likely.
The trick is to exploit Visual Studio’s “find in files” feature. This will bring up each occurrence of the dead code in the Find Results window so you can navigate to each instance of dead code quickly. Here are some regular expressions that I use to find dead code:
//.*; //:b*(if|while|for|do) //:b*# \#:b*if:b+:b*$
The first two look for code commented out with the C++ single-line comment token (//). The second two look for either commented-out preprocessor directives or preprocessor directives that are always true or false. Looking for code commented out with the multi-line comment tokens (/* and */) is a little bit harder, but you can find likely candidates with something like this:
You might need to adjust that for the style of commenting used in your code-base. You’ll notice that commented-out code always tends to be commented out in a certain way. I don’t know why people comment out code permanently. The compiler isn’t seeing it. Putting it in the middle of stuff the compiler does sees just plays tricks on your brain. Your brain can’t turn its visual analysis on and off based on comment strings, even with syntax highlighting. Its still code in your visual field and it goes into your brain whether you like it or not and you have to spend brain cycles purposefully ignoring it. Just do your brain a favor and delete it! If you ever should need it again for some reason, you can always get it back out of the source code control system.
While I’m on the subject of source code control systems, let me make a few recommendations about how you should delete dead code. First, get all your other checkins done before you go hunting for dead code. Once all your code is checked in and your unit tests are passing, go dead code hunting and ferret as much of it out of the bushes as you can. Kill it mercilessly. Don’t do anything else while your killing dead code. If you don’t have enough time in a single commit cycle to remove all the identified dead code from your code base, try working on it one project at a time instead of comprehensively. After you’ve deleted it all and your code is compiling and all unit tests are passing, then commit the changes and only these changes. Use the phrase “Deleting dead code” or something similar on your commit message. This way, when people look at the commit log, they can quickly identify commits that were deleting dead code. If for some reason you need to turn that deleted dead code into walking zombie code (“living dead” code?), then you can quickly find it in the commit log.
Now, here’s one more Visual Studio trick for you that will make it easy to navigate through all these potentially dead pieces of code and remove them. You see, “Find in files…” sends its output to the Find Results window. (There are two find results windows and you can select which one gets the output of this particular search in the Result Options section of the Find and Replace dialog.) You see, I like to stay keyboard centric when I’m operating in Visual Studio. However, the standard keyboard bindings for Visual Studio doesn’t contain a shortcut to display the find results window. Of course it will display itself when you run the search. However, getting the keyboard focus back to the search results is the important bit of this trick.
So go to Tools / Options… / Keyboard in Visual Studio. Show commands containing “View.FindResults”. You should see two entries in the list box underneath reading “View.FindResults1” and “View.FindResults2”. Select the Find Results 1 item and use the new shortcut in the Global scope by selecting Global in the combobox. To the right of the combobox type Alt+1 and then click Assign. Repeat the process for the Find Results 2 window if you use both find result windows in your searches.
OK, so now that we’ve got the keyboard binding created, the dead code hunt begins with you invoking “Find in files…” on whatever portion of your code base you want to search for dead code. I like to go project by project on large solutions containing many projects. I’ll eliminate all the dead code from one project and commit that before moving onto the next project.
Once you have your search results, the dead code hunt looks like this sequence of key presses: Alt+1, DownArrow, Return, //delete dead code. Let’s break that down:
- Alt+1: display Find Results 1 window and send keyboard focus to that window
- DownArrow: in the Find Results 1 window, move the cursor down one line. This advances to the next line in the search results. Each individual item matching the search expression is shown on its own line, so this advances to the next match to the search expression.
- Return: when you press return in the find results window, it navigates to whatever source file and line are listed on the line of the find results window that contains the cursor. This navigates to the source code matched.
Now you can examine the offending code in question and decide whether or not to delete it. Most of the time, you will. As you repeat this process, you can quickly get into a rhythm of keypresses that will rapidly take you through most, if not all, the instances of dead code. Thanks to the keyboard shortcut applied to the View.FindResults1 command, we don’t have to leave the keyboard to use the mouse to navigate over to the window and double-click the next find result. For lots of sprinkled single-lines of code commented out, this really makes quick work of that.
Refactoring is like backpacking. You always plan on packing out more trash than you brought with you. Deleting dead code is like getting rid of that dead fish at the campsite. You leave the world a better place. Your team will thank you for it.