Blog 5 min read

Tracking the hidden duplicate code in a C++ code base.

Share this article
Tracking the hidden duplicate code in a C++ code base.

It’s well known that the presence of duplicate code has a negative impact on software development and maintenance. Indeed, a major drawback is that when an instance of duplicate code is changed to fix bugs or add new features, its counterparts have to be changed simultaneously.

The most common cause of duplicate code is copy/paste operations, where the source code is exactly the same in two or more places. This practice is discouraged in many articles, books, and websites. However, it’s not always easy to follow the recommendations, and the developer often chooses the easy solution: copy/paste.

There are many tools to detect this kind of cloned code; CCFinderX is one of the interesting open source tools available. CCFinderX is a code-clone detector that detects code clones (duplicated code fragments) in source files written in Java, C/C++, COBOL, VB and C#. It enables user-side customization of a preprocessor and provides interactive, metrics-based analysis.

Using the appropriate tool makes it easy to detect duplicate code produced by copy/paste operations; however, there are some cases where cloned code is not trivial to detect.

Hidden duplicate codeCase 1: Modified copy/pasted code.

As described before, the major problem with copy/pasted code is that when an instance of duplicate code is changed, its counterparts have to be changed simultaneously. Unfortunately this is not always the case, and the duplicate code instances become different.

To avoid this kind of hidden duplicate code, don’t hesitate to use a tool like CCFinderX to discover the duplicate code instances, and at least tag them by adding comments if you don’t have time to refactor your code. This is very useful when a developer tries to change a duplicate code instance: he will be notified that other places have the same code. However, if the developer is not informed, he will change only one place, and it will become very difficult to detect the modified duplicate code later.

Case 2: Similar functionality

Copy/paste operations are not the only source of duplicate code; another cause is when similar functionality is implemented.

Here’s a brief description of this second source of duplicate code from Wikipedia:

Functionality that is very similar to that in another part of a program is required and a developer independently writes code that is very similar to what exists elsewhere. Studies suggest, that such independently rewritten code is typically not syntactically similar.

Tracking hidden duplicate code

When the duplicate code is not exactly the same, no tool can give you reliable results: it can only report suspicious duplicate code, and it’s the developer’s responsibility to check whether it’s really cloned code or just a false positive.

Each tool uses a specific algorithm to track this kind of duplicate code. We didn’t test all of these tools, but I think most of them are worth trying at least once: they could give you interesting results that help you improve the design and implementation of your code, as we will see later in this post.

In our case we will use an algorithm that consists of defining sets of methods that use the same members, i.e. calling the same methods, reading the same fields and writing the same fields. We call these sets suspect-sets. Suspect-sets are sorted by the number of common members used.

CppDepend implements this algorithm as a CppDepend Power-Tool. Power-Tools are a set of open-source tools based on the CppDepend.API. The source code of the Power-Tools can be found in $CppDependInstallPath$\CppDepend.PowerTools.SourceCode\CppDepend.PowerTools.sln.

Let’s see how efficient this algorithm is by searching for duplicate code in the Irrlicht 3D engine code base.

Case study: Irrlicht 3D engine

The Irrlicht Engine is an open-source high-performance realtime 3D engine written in C++. It is completely cross-platform.

Here are two of the suspicious duplicate code instances detected:

1- Exact duplicate code

In this case, the 18 methods detected use the same 3 methods, read the same 2 fields and write the same 9 fields.

clone5

After checking the source code of these methods, it turns out to be an exact code duplicate. However, other tools are better suited to detect this kind of duplication, and our algorithm has no added value when it comes to exact cloned code.

2- Similar functionality

Here’s a second suspicious duplicate: it concerns four methods that use the same 11 methods, read the same 6 fields and write the same 2 fields.

clone6

After checking the source code of these four methods, it’s not exactly the same code. However, they implement a unique layout algorithm, so here I’d vote for a refactoring.

To better explain this case, here’s the relationship between the classes concerned by the duplicate code:

clone7

OnSetConstants is declared in the IShaderConstantSetCallBack interface and implemented by all the derived classes. All four implementations have the same layout algorithm, and in such cases the template method pattern is a good solution to refactor the existing implementation.

When testing this algorithm on many C++ open source projects, we were very surprised to find that many duplicate code cases are similar to this one, and that the template method pattern is rarely used.

Conclusion

Tracking duplicate code is very useful for improving both the implementation and the design of your projects. Fortunately, many tools exist to detect cloned code, and it’s recommended to run one of these tools periodically and at least tag the duplicate instances.

Share this article