# Dead Code

## Summary


Dead code is any code that's never executed, or if executed, the execution has no effect on the application's behaviour.  

Dead code adds unnecessary complexity to the codebase. It makes the codebase more difficult to understand and maintain in the long run. It impacts performance and security. In some cases, due to poor software engineering practices, dead code can "come back to life" and cause catastrophic failures. It's therefore recommended to remove dead code. 

Tools and techniques are available to help developers get rid of dead code. But developers tend to leave them around rather than remove them. It's been said that, 

> Deleting dead code is not a technical problem; it is a problem of mindset and culture.

## Discussion

### What's the definition of dead code?

Dead code is any code that has no effect on the application's behaviour. This is a simple and useful definition. Looking into the details, we identify some alternatives to this definition.

Code that is unnecessarily executed is called **redundant code**. This would include variable assignments or function returns that are subsequently never used. A subset of this may be called **partially dead code** that refers to code that's essential only on some program paths.  

Code that can't be reached or executed on any program path is called **unreachable code**. This could happen if there's an unconditional function return and there's code that follows the return statement. Code that's commented is another example. A superset of this is **unused code** that could be executed but it's not executed because the user never triggers it. 


### What are the different types of dead code?

Dead code can be of the following types: 

    + **Dead Types**: Types are defined but not used anywhere. This includes types used by only other types but the latter themselves are not used anywhere. Public types should not be considered dead since they maybe called by client code.
    + **Dead Methods**: Like dead types but applicable for methods.
    + **Dead Fields**: Unused fields or fields that are only initialized but not used anywhere in the code. Dead fields include attributes of classes common in object-oriented programming languages.
    + **Dead Parameters**: Maybe considered as a special case of dead fields. For example, a function accepts four parameters but only three are used by the function.Since public types, methods and fields could be called by client code, we don't consider them as dead during static analysis or compilation. However, a linker can still identify dead code and remove them if they see that client code is not calling them. An example of this is *R8* code shrinker that developers use in Android projects. 


### What problems can dead code cause?

Dead code introduces unnecessary **complexity** and confusion. People who maintain code are usually not the same as those who created it. With dead code around, it's hard to know what's safe to delete or update. Developers may even maintain dead code (and their test cases) without realizing that it's a waste of effort. From a design perspective, dead code increases or preserves coupling among classes. This in turn makes code refactoring more difficult. 

Dead code takes up extra **space**. Program size is larger and so too its runtime footprint. 

Dead code that executes without changing application's functional behaviour but may affect **performance**. CPU cycles are spent in executing redundant code. 

Dead code that hasn't been touched for a long time may also contain **security** issues that could be exploited by hackers. It's smarter to delete such code than maintain it. 

A **patent** is infringed only if the code that implements the claimed invention actually executes. Therefore, patent holders will have a weaker case if some of their code is dead. This is yet another reason to identify dead code. 


### Could you share some real-world instances of dead code?

A high-profile example is that of Knight Capital Group that lost $440 million in a single day on the NYSE due to dead code. This happened on August 1st, 2012 though the dead code had been unused since 2003. The problem was triggered because a dead feature flag was repurposed for some new code. This unintentionally activated the dead code that had been designed for only test environments. The codebase had also been refactored without adequate regression testing. Moreover, deployment was done manually without a proper reviewal process. 

In 2014, Apple fixed a security vulnerability that was attributed to a copy-paste edit that lead to dead code. A duplicate line of code allowed an attacker to bypass an authentication check, which became dead code. Static code analysis would have caught this problem. Informal peer review, formal code inspection, test coverage (line and path coverage) and training developers are other ways this could have been prevented or caught earlier. 


### Why do we have dead code?

Dead code arises due to **software maintenance** and **software aging**. For example, a new fragment of code might make another code fragment dead. Developers are either unaware of this or think that such code may be needed again someday. When software ages, dead code due to obsolete features is a common reason. 

Where a codebase is inherited from another company, we can have **inherited dead code**. When developers recognize the dead code, they might comment it out or add comments to flag it. They may remove it only if it's low risk and low cost. 

Sometimes code is **created dead** with the expectation that it could be used in future. In classes, the use of getters and setters is such an example. Unclear or incomplete specifications are further reasons for dead code. Code reuse can cause dead code since not all interfaces or functions may be used. 

Sometimes dead code is active during **testing** but not in production. Developers therefore don't consider removing it. On the contrary, lack of automated regression testing makes developers wary of any refactoring. 


### What are some tools and techniques to eliminate dead code?

An easy way to find and eliminate dead code is a good IDE. Unused files can also be removed. Unnecessary classes can be inlined. Class hierarchy can be collapsed. Eclipse, Findbugs, PMD, and NDepend are some useful IDEs or tools. 

Languages such as JavaScript have good linting tools to catch dead code. For Go, Grind package can be considered. For R, there's `rco`. For Python, there's Vulture for static code analysis. Although Python is a dynamic language, Vulture can improve code quality. 

Where developers suspect dead code, they can log messages. More generally, it's a good practice to log API calls. If such messages appear at runtime, we can be assured that the code is not entirely dead. However, absence of these messages in the log doesn't guarantee that the code is dead. 

For JavaScript frontend code, minifiers remove dead code for production builds. Likewise, there are options to C++ compilers and linkers that eliminate dead code. These reduce program size and perhaps improve performance. However, they don't solve the problem of dead code at the source, which implies that software maintenance continues to be complex. 

## Milestones

1970

In this decade, there's research towards better compilers, program certification and program optimization. For example, Rosen's 1977 paper titled *High-Level Data Flow Analysis* adopts directed graphs as an analysis tool. These research initiatives facilitate dead code elimination. 

1994

Based on techniques for partial redundancy elimination, Knoop et al. present an optimal method for **partial dead code elimination**. Their method is optimal in the sense that any remaining partially dead code can't be eliminated without changing the code structure or its semantics. 

1998

In a book about software refactoring, Brown et al. take note of "unused code frozen in an ever-changing design." They call this **lava flow**. 

1999

Martin Fowler in his book titled *Refactoring: Improving the Design of Existing Code* identifies 22 code smells and suggests ways to remove them. However, he doesn't explicitly mention dead code as a code smell. 

Dec  
2003

Bolton and Ung file for a patent with the title *Partial dead code elimination optimizations for program code conversion*. They identify partially dead register definitions that can be eliminated towards more optimized intermediate representation of the code. 

Nov  
2018

As part of Android Studio 3.3 beta, Google releases **R8** for code shrinking. With R8, APK size reduces. R8 gets rid of unused code and resources. It also does code minification to save space. Proguard is another tool that does this but R8 does it faster while achieving similar results. 

Dec  
2020

In an analysis of code smells, dos Reis et al. include dead code as one of the code smells. From the 83 studies selected for the analysis, they find that 4.8% contain dead code. The most prominent code smell is the God Class, present in 51.8% of the studies.