Is a Static Analyzer Necessary in Software Development?
Abstract
My name is Andrey and I’m a student, my point of interests is software development, and I recently learned about the PVS-Studio static code analyzer and decided to try it on one small project of mine. The latest program version can be downloaded from the developer’s site. During installation, it was offered to install a standalone version and a plugin for Visual Studio. Note that the package comes with extensive documentation in English. Unfortunately, PVS-Studio didn’t find any errors in my project, which is written in C#. But it’s because the program is small and there’s only me working on it, so I’m well familiar with it’s entire code.
Then I spotted the EntityFramework project, whose source code can be downloaded here.
EntityFramework is an object-relational mapping framework, a popular ORM tool by Microsoft for .NET developers.
Testing
The testing was done in the Visual Studio 2015 IDE. All the settings were left to their default values, as recommended by the developers, except for the help language (IntegratedHelpLanguauge), which I changed to Russian.
The analysis didn’t take long and revealed 85 errors, with the following distribution across the error-severity levels:
- 16 “High”-level errors
- 15 “Medium”-level errors
- 54 “Low”-level errors
I think these statistics are pretty good, but instead of jumping to conclusions, let’s take a closer look at the most interesting errors found by the analyzer.
One nice feature of the tool is that clicking on the link with the error code takes you to the error description in selected language. The first message reads as follows:
Let’s examine the code with the eror: extension method Count returns a value but it wasn’t assigned to the variable; that is, executing this code doesn’t affect anything. There are several instances of this error in the project.
Here is another high-level error. PVS-Studio warns that the if (A) (…) else if (A) pattern was detected. Such errors are quite common when writing code using the copy-paste technique.
In this case, the following condition is tepeated several times in lines 302 and 352:
if (SchemaElement.CanHandleAttribute(reader, DbProviderManifest.NullableFacetName))
{
HandleNullableAttribute(reader);
return true;
}
…
else if (SchemaElement.CanHandleAttribute(reader, DbProviderManifest.NullableFacetName))
{
HandleNullableAttribute(reader);
return true;
}
The next error deals with the && operator having identical operands:
The next interesting error is found in several classes at once and has to do with testing a wrong object for null.
Let’s examine the Equals method, where the error was spotted:
public override bool Equals(object obj)
{
var right = obj as MemberPath;
if (obj == null)
{
return false;
}
return Equals(right);
}
The as operator is used to cast the obj variable in line 529 to the MemberPath type. If the cast isn’t possible, the variable right will be assigned a null value. But then, the obj variable, instead of right, is tested for null, so right variable may end up with a null value.
The next error, again, deals with code copying, but this time it’s about identical expressions in the if() … else() construct:
Now let’s move to medium-level warnings. The first error here deals with assigning a value twice to variable clrElementType:
The code’s logic suggests that the second block must be executed when ospaceElementTypeUsage != null, i.e. it is the if() … else() construct that the programmer meant to use here.
Most of the low-level warnings deal with comparing two variables of type double:
The specifics of real-number representation in computer memory require that variables of type double be tested for equality by comparing their absolute values’ difference with certain Epsilon accuracy, instead of comparing them directly.
Another error is about having two identical methods ProcessAndOverConstantPredicate1. This error, too, seems to result from code copying:
Let’s finish our review of errors found in EntityFramework by the PVS-Studio static analyzer here and sum it all up.
Conclusion
The conclusion I’ve drawn for myself is that a static analyzer is not necessary in a small projects, where the developers know their code in full; but it is indispensable in large projects, no matter how skilled the developers are. With EntityFramework as an example, I’ve discussed the common errors, which can be found in any big project and from which even Microsoft developers aren’t secure.